From d1fc657554670bcc555e086a94ca225b75a874f6 Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Wed, 11 Nov 2026 09:22:34 -0500 Subject: [PATCH 1/2] Every log line starts with its time in UTC, so a call that sounded wrong can be lined up with what the log says happened then The Logs window reads the level after the time, and still reads files written before it. Co-Authored-By: Claude Opus 5.5 --- crates/protocol/src/log_policy.rs | 38 ++++++++++++++++++++++++++++++- crates/tinyclient/src/log_tail.rs | 16 +++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/crates/protocol/src/log_policy.rs b/crates/protocol/src/log_policy.rs index 0211a6fe..331be379 100644 --- a/crates/protocol/src/log_policy.rs +++ b/crates/protocol/src/log_policy.rs @@ -281,6 +281,30 @@ fn cut(text: &str) -> &str { /// 32 hex characters shared by the window, chatd, and mediad. An invalid `TINYCLIENT_SESSION` /// is ignored and a new id is generated. +/// A moment as the start of a log line: UTC to the millisecond, `2026-11-11T14:03:22.123Z`. +pub fn stamp(at: SystemTime) -> String { + let since = at.duration_since(UNIX_EPOCH).unwrap_or_default(); + let secs = since.as_secs(); + let (days, of_day) = ((secs / 86_400) as i64, secs % 86_400); + // Days since 1970-01-01 to a civil date (Howard Hinnant's `civil_from_days`). + let z = days + 719_468; + let era = z.div_euclid(146_097); + let doe = z.rem_euclid(146_097); + let yoe = (doe - doe / 1_460 + doe / 36_524 - doe / 146_096) / 365; + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + let mp = (5 * doy + 2) / 153; + let day = doy - (153 * mp + 2) / 5 + 1; + let month = if mp < 10 { mp + 3 } else { mp - 9 }; + let year = yoe + era * 400 + i64::from(month <= 2); + format!( + "{year:04}-{month:02}-{day:02}T{:02}:{:02}:{:02}.{:03}Z", + of_day / 3_600, + of_day / 60 % 60, + of_day % 60, + since.subsec_millis() + ) +} + pub fn session_id() -> &'static str { let mut slot = SESSION.lock().unwrap_or_else(|err| err.into_inner()); if let Some(id) = *slot { @@ -617,9 +641,13 @@ where message: &recorder.message, fields: &borrowed, }; - let Some(mut line) = render(&policy, self.sink, &parts) else { + let Some(rendered) = render(&policy, self.sink, &parts) else { return; }; + // When, so a line can be lined up with what someone heard or saw at the time. + let mut line = stamp(SystemTime::now()); + line.push(' '); + line.push_str(&rendered); line.push_str(" session="); line.push_str(session_id()); match self.sink { @@ -784,6 +812,14 @@ pub fn current() -> Option<&'static LogGuard> { mod tests { use super::*; + #[test] + fn a_line_starts_with_its_time_in_utc() { + assert_eq!(stamp(UNIX_EPOCH), "1970-01-01T00:00:00.000Z"); + // 2026-11-11 14:03:22.123 UTC, and a leap day. + assert_eq!(stamp(UNIX_EPOCH + Duration::from_millis(1_794_405_802_123)), "2026-11-11T14:03:22.123Z"); + assert_eq!(stamp(UNIX_EPOCH + Duration::from_secs(1_709_164_800)), "2024-02-29T00:00:00.000Z"); + } + fn line_of(value: Option) -> String { match value { Some(value) => value, diff --git a/crates/tinyclient/src/log_tail.rs b/crates/tinyclient/src/log_tail.rs index 042dadc4..816d8c42 100644 --- a/crates/tinyclient/src/log_tail.rs +++ b/crates/tinyclient/src/log_tail.rs @@ -78,9 +78,14 @@ impl Level { } } -/// The level a file line starts with (`render` writes `warn chatd::media ...`). `None` for a -/// line that does not, such as the second line of a message with a newline in it. +/// The level a file line starts with, after its time (`2026-11-11T14:03:22.123Z warn chatd::media +/// ...`; files from before the time was written start with the level). `None` for a line that +/// does not, such as the second line of a message with a newline in it. pub fn level_of(line: &str) -> Option { + let line = match line.split_once(' ') { + Some((first, rest)) if is_stamp(first) => rest, + _ => line, + }; Some(match line.split_once(' ').map_or(line, |(word, _)| word) { "error" => Level::Error, "warn" => Level::Warn, @@ -91,6 +96,11 @@ pub fn level_of(line: &str) -> Option { }) } +/// The time a file line starts with: `2026-11-11T14:03:22.123Z`. +fn is_stamp(word: &str) -> bool { + word.len() == 24 && word.ends_with('Z') && word.as_bytes()[10] == b'T' && word[..4].bytes().all(|b| b.is_ascii_digit()) +} + pub fn is_noise(text: &str) -> bool { NOISE.iter().any(|noise| text.contains(noise)) } @@ -310,6 +320,8 @@ mod tests { assert_eq!(level_of("error log RefCell already borrowed"), Some(Level::Error)); assert_eq!(level_of("trace mediad x"), Some(Level::Trace)); assert_eq!(level_of("debug"), Some(Level::Debug)); + assert_eq!(level_of("2026-11-11T14:03:22.123Z warn mediad::tiny voice x session=ab"), Some(Level::Warn)); + assert_eq!(level_of("2026-11-11T14:03:22.123Z"), None); assert_eq!(level_of(" at line 2 of a message"), None); assert_eq!(level_of("warning chatd"), None); assert_eq!(level_of(""), None); From 71949c9949d08c7c7ff9f1fa789f2690c8a91574 Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Wed, 11 Nov 2026 09:22:34 -0500 Subject: [PATCH 2/2] Voices no longer sound under water: libopus conceals losses and late packets in every mode, and the playout is paced instead of looped - vendor/unsafe-libopus: c2rust turned silk_SAT16's lower bound into +32768, so SILK concealment and comfort noise came out at full scale. mediad played a repeated pitch period there instead, which is the under-water voice. Six constants fixed, marked "tinyclient patch". - A packet not here yet in mid-speech is carried on by libopus and fades over 60 ms, not looped. - The jitter buffer is sized from how late one packet in a hundred came over the last 10 s (a stall's backlog counts once), not only from three times the average. - A frame plays one pitch period longer when the buffer runs short and shorter when it holds more than it needs in mid-speech, so a stall's delay is given back while the person keeps talking. - Each voice logs what its playout made up every 10 s when anything was, and over the whole call. - e2e/scenarios/voice-playout: a Wi-Fi-shaped call through a real receive stream. Co-Authored-By: Claude Opus 5.5 --- Cargo.lock | 2 - Cargo.toml | 7 + crates/mediad/src/jitter.rs | 46 +- crates/mediad/src/lib.rs | 1 + crates/mediad/src/main.rs | 11 + crates/mediad/src/media.rs | 277 +- crates/mediad/src/opus.rs | 160 +- crates/mediad/src/pace.rs | 139 + crates/mediad/src/stats.rs | 109 +- crates/mediad/src/tiny.rs | 8 +- e2e/scenarios/voice-playout/drive.linux.sh | 9 + e2e/scenarios/voice-playout/drive.macos.sh | 9 + e2e/scenarios/voice-playout/drive.py | 86 + e2e/scenarios/voice-playout/drive.windows.ps1 | 17 + e2e/scenarios/voice-playout/scenario.json | 12 + vendor/unsafe-libopus/Cargo.toml | 48 + vendor/unsafe-libopus/Cargo.toml.orig | 44 + vendor/unsafe-libopus/LICENSE | 44 + vendor/unsafe-libopus/README.md | 95 + vendor/unsafe-libopus/src/celt/bands.rs | 2145 ++++++++++ vendor/unsafe-libopus/src/celt/celt.rs | 224 ++ .../unsafe-libopus/src/celt/celt_decoder.rs | 1570 ++++++++ .../unsafe-libopus/src/celt/celt_encoder.rs | 3513 +++++++++++++++++ vendor/unsafe-libopus/src/celt/celt_lpc.rs | 236 ++ vendor/unsafe-libopus/src/celt/cwrs.rs | 457 +++ vendor/unsafe-libopus/src/celt/entcode.rs | 117 + vendor/unsafe-libopus/src/celt/entdec.rs | 200 + vendor/unsafe-libopus/src/celt/entenc.rs | 302 ++ vendor/unsafe-libopus/src/celt/float_cast.rs | 13 + vendor/unsafe-libopus/src/celt/kiss_fft.rs | 251 ++ vendor/unsafe-libopus/src/celt/laplace.rs | 107 + vendor/unsafe-libopus/src/celt/mathops.rs | 119 + vendor/unsafe-libopus/src/celt/mdct.rs | 238 ++ vendor/unsafe-libopus/src/celt/modes.rs | 86 + .../src/celt/modes/static_modes_float_h.rs | 883 +++++ vendor/unsafe-libopus/src/celt/pitch.rs | 600 +++ vendor/unsafe-libopus/src/celt/quant_bands.rs | 713 ++++ vendor/unsafe-libopus/src/celt/rate.rs | 625 +++ ...ibopus__celt__cwrs__test__pvq_u_table.snap | 1382 +++++++ .../src/celt/tests/test_unit_cwrs32.rs | 2684 +++++++++++++ .../src/celt/tests/test_unit_dft.rs | 326 ++ .../src/celt/tests/test_unit_entropy.rs | 1423 +++++++ .../src/celt/tests/test_unit_laplace.rs | 931 +++++ .../src/celt/tests/test_unit_mathops.rs | 248 ++ .../src/celt/tests/test_unit_mdct.rs | 415 ++ .../src/celt/tests/test_unit_rotation.rs | 119 + .../src/celt/tests/test_unit_types.rs | 41 + vendor/unsafe-libopus/src/celt/vq.rs | 371 ++ vendor/unsafe-libopus/src/externs.rs | 104 + vendor/unsafe-libopus/src/lib.rs | 291 ++ vendor/unsafe-libopus/src/silk/A2NLSF.rs | 198 + vendor/unsafe-libopus/src/silk/CNG.rs | 550 +++ .../src/silk/HP_variable_cutoff.rs | 67 + vendor/unsafe-libopus/src/silk/Inlines.rs | 132 + .../src/silk/LPC_analysis_filter.rs | 76 + vendor/unsafe-libopus/src/silk/LPC_fit.rs | 84 + .../src/silk/LPC_inv_pred_gain.rs | 395 ++ .../src/silk/LP_variable_cutoff.rs | 128 + vendor/unsafe-libopus/src/silk/NLSF2A.rs | 115 + vendor/unsafe-libopus/src/silk/NLSF_VQ.rs | 48 + .../src/silk/NLSF_VQ_weights_laroia.rs | 47 + vendor/unsafe-libopus/src/silk/NLSF_decode.rs | 92 + .../src/silk/NLSF_del_dec_quant.rs | 238 ++ vendor/unsafe-libopus/src/silk/NLSF_encode.rs | 124 + .../unsafe-libopus/src/silk/NLSF_stabilize.rs | 188 + vendor/unsafe-libopus/src/silk/NLSF_unpack.rs | 22 + vendor/unsafe-libopus/src/silk/NSQ.rs | 575 +++ vendor/unsafe-libopus/src/silk/NSQ_del_dec.rs | 1070 +++++ vendor/unsafe-libopus/src/silk/PLC.rs | 814 ++++ vendor/unsafe-libopus/src/silk/SigProc_FIX.rs | 36 + vendor/unsafe-libopus/src/silk/VAD.rs | 282 ++ vendor/unsafe-libopus/src/silk/VQ_WMat_EC.rs | 104 + .../src/silk/ana_filt_bank_1.rs | 76 + vendor/unsafe-libopus/src/silk/biquad_alt.rs | 68 + vendor/unsafe-libopus/src/silk/bwexpander.rs | 25 + .../unsafe-libopus/src/silk/bwexpander_32.rs | 16 + .../src/silk/check_control_input.rs | 94 + vendor/unsafe-libopus/src/silk/code_signs.rs | 75 + vendor/unsafe-libopus/src/silk/control_SNR.rs | 67 + .../src/silk/control_audio_bandwidth.rs | 88 + .../unsafe-libopus/src/silk/control_codec.rs | 390 ++ vendor/unsafe-libopus/src/silk/debug.rs | 1 + vendor/unsafe-libopus/src/silk/dec_API.rs | 512 +++ vendor/unsafe-libopus/src/silk/decode_core.rs | 494 +++ .../unsafe-libopus/src/silk/decode_frame.rs | 91 + .../unsafe-libopus/src/silk/decode_indices.rs | 132 + .../src/silk/decode_parameters.rs | 119 + .../unsafe-libopus/src/silk/decode_pitch.rs | 69 + .../unsafe-libopus/src/silk/decode_pulses.rs | 102 + .../unsafe-libopus/src/silk/decoder_set_fs.rs | 78 + vendor/unsafe-libopus/src/silk/define.rs | 62 + vendor/unsafe-libopus/src/silk/enc_API.rs | 873 ++++ .../unsafe-libopus/src/silk/encode_indices.rs | 198 + .../unsafe-libopus/src/silk/encode_pulses.rs | 232 ++ .../src/silk/float/LPC_analysis_filter_FLP.rs | 172 + .../src/silk/float/LTP_analysis_filter_FLP.rs | 48 + .../src/silk/float/LTP_scale_ctrl_FLP.rs | 33 + .../src/silk/float/apply_sine_window_FLP.rs | 33 + .../src/silk/float/autocorrelation_FLP.rs | 20 + .../src/silk/float/burg_modified_FLP.rs | 177 + .../src/silk/float/bwexpander_FLP.rs | 11 + .../src/silk/float/corrMatrix_FLP.rs | 50 + .../src/silk/float/encode_frame_FLP.rs | 576 +++ .../src/silk/float/energy_FLP.rs | 18 + .../src/silk/float/find_LPC_FLP.rs | 114 + .../src/silk/float/find_LTP_FLP.rs | 45 + .../src/silk/float/find_pitch_lags_FLP.rs | 125 + .../src/silk/float/find_pred_coefs_FLP.rs | 129 + .../src/silk/float/inner_product_FLP.rs | 18 + .../unsafe-libopus/src/silk/float/k2a_FLP.rs | 21 + .../silk/float/noise_shape_analysis_FLP.rs | 378 ++ .../src/silk/float/pitch_analysis_core_FLP.rs | 776 ++++ .../src/silk/float/process_gains_FLP.rs | 102 + .../src/silk/float/residual_energy_FLP.rs | 47 + .../src/silk/float/scale_copy_vector_FLP.rs | 22 + .../src/silk/float/scale_vector_FLP.rs | 17 + .../src/silk/float/schur_FLP.rs | 38 + .../unsafe-libopus/src/silk/float/sort_FLP.rs | 41 + .../src/silk/float/structs_FLP.rs | 53 + .../silk/float/warped_autocorrelation_FLP.rs | 43 + .../src/silk/float/wrappers_FLP.rs | 225 ++ vendor/unsafe-libopus/src/silk/gain_quant.rs | 164 + .../unsafe-libopus/src/silk/init_decoder.rs | 26 + .../unsafe-libopus/src/silk/init_encoder.rs | 21 + .../src/silk/inner_prod_aligned.rs | 16 + vendor/unsafe-libopus/src/silk/interpolate.rs | 20 + vendor/unsafe-libopus/src/silk/lin2log.rs | 9 + vendor/unsafe-libopus/src/silk/log2lin.rs | 36 + vendor/unsafe-libopus/src/silk/macros.rs | 10 + vendor/unsafe-libopus/src/silk/mathops.rs | 3 + .../src/silk/pitch_est_tables.rs | 62 + .../unsafe-libopus/src/silk/process_NLSFs.rs | 97 + .../src/silk/quant_LTP_gains.rs | 139 + .../unsafe-libopus/src/silk/resampler/ar2.rs | 18 + .../src/silk/resampler/down2.rs | 47 + .../src/silk/resampler/down2_3.rs | 114 + .../src/silk/resampler/down_fir.rs | 255 ++ .../src/silk/resampler/iir_fir.rs | 112 + .../unsafe-libopus/src/silk/resampler/mod.rs | 275 ++ .../unsafe-libopus/src/silk/resampler/rom.rs | 59 + .../src/silk/resampler/up2_hq.rs | 110 + vendor/unsafe-libopus/src/silk/shell_coder.rs | 179 + vendor/unsafe-libopus/src/silk/sigm_Q15.rs | 22 + vendor/unsafe-libopus/src/silk/sort.rs | 51 + .../src/silk/stereo_LR_to_MS.rs | 407 ++ .../src/silk/stereo_MS_to_LR.rs | 172 + .../src/silk/stereo_decode_pred.rs | 38 + .../src/silk/stereo_encode_pred.rs | 39 + .../src/silk/stereo_find_predictor.rs | 90 + .../src/silk/stereo_quant_pred.rs | 55 + vendor/unsafe-libopus/src/silk/structs.rs | 247 ++ .../unsafe-libopus/src/silk/sum_sqr_shift.rs | 41 + .../unsafe-libopus/src/silk/table_LSF_cos.rs | 11 + vendor/unsafe-libopus/src/silk/tables_LTP.rs | 115 + .../src/silk/tables_NLSF_CB_NB_MB.rs | 87 + .../src/silk/tables_NLSF_CB_WB.rs | 114 + vendor/unsafe-libopus/src/silk/tables_gain.rs | 9 + .../unsafe-libopus/src/silk/tables_other.rs | 45 + .../src/silk/tables_pitch_lag.rs | 15 + .../src/silk/tables_pulses_per_block.rs | 113 + .../silk/tests/test_unit_LPC_inv_pred_gain.rs | 174 + vendor/unsafe-libopus/src/src/analysis.rs | 1596 ++++++++ .../unsafe-libopus/src/src/mapping_matrix.rs | 1199 ++++++ vendor/unsafe-libopus/src/src/mlp.rs | 403 ++ vendor/unsafe-libopus/src/src/mlp_data.rs | 282 ++ vendor/unsafe-libopus/src/src/opus.rs | 367 ++ vendor/unsafe-libopus/src/src/opus_decoder.rs | 1122 ++++++ vendor/unsafe-libopus/src/src/opus_defines.rs | 76 + vendor/unsafe-libopus/src/src/opus_encoder.rs | 3034 ++++++++++++++ .../src/src/opus_multistream.rs | 59 + .../src/src/opus_multistream_decoder.rs | 638 +++ .../src/src/opus_multistream_encoder.rs | 1750 ++++++++ vendor/unsafe-libopus/src/src/opus_private.rs | 17 + .../src/src/opus_projection_decoder.rs | 311 ++ .../src/src/opus_projection_encoder.rs | 554 +++ vendor/unsafe-libopus/src/src/repacketizer.rs | 435 ++ vendor/unsafe-libopus/src/varargs.rs | 92 + 177 files changed, 49871 insertions(+), 118 deletions(-) create mode 100644 crates/mediad/src/pace.rs create mode 100644 e2e/scenarios/voice-playout/drive.linux.sh create mode 100644 e2e/scenarios/voice-playout/drive.macos.sh create mode 100644 e2e/scenarios/voice-playout/drive.py create mode 100644 e2e/scenarios/voice-playout/drive.windows.ps1 create mode 100644 e2e/scenarios/voice-playout/scenario.json create mode 100644 vendor/unsafe-libopus/Cargo.toml create mode 100644 vendor/unsafe-libopus/Cargo.toml.orig create mode 100644 vendor/unsafe-libopus/LICENSE create mode 100644 vendor/unsafe-libopus/README.md create mode 100644 vendor/unsafe-libopus/src/celt/bands.rs create mode 100644 vendor/unsafe-libopus/src/celt/celt.rs create mode 100644 vendor/unsafe-libopus/src/celt/celt_decoder.rs create mode 100644 vendor/unsafe-libopus/src/celt/celt_encoder.rs create mode 100644 vendor/unsafe-libopus/src/celt/celt_lpc.rs create mode 100644 vendor/unsafe-libopus/src/celt/cwrs.rs create mode 100644 vendor/unsafe-libopus/src/celt/entcode.rs create mode 100644 vendor/unsafe-libopus/src/celt/entdec.rs create mode 100644 vendor/unsafe-libopus/src/celt/entenc.rs create mode 100644 vendor/unsafe-libopus/src/celt/float_cast.rs create mode 100644 vendor/unsafe-libopus/src/celt/kiss_fft.rs create mode 100644 vendor/unsafe-libopus/src/celt/laplace.rs create mode 100644 vendor/unsafe-libopus/src/celt/mathops.rs create mode 100644 vendor/unsafe-libopus/src/celt/mdct.rs create mode 100644 vendor/unsafe-libopus/src/celt/modes.rs create mode 100644 vendor/unsafe-libopus/src/celt/modes/static_modes_float_h.rs create mode 100644 vendor/unsafe-libopus/src/celt/pitch.rs create mode 100644 vendor/unsafe-libopus/src/celt/quant_bands.rs create mode 100644 vendor/unsafe-libopus/src/celt/rate.rs create mode 100644 vendor/unsafe-libopus/src/celt/snapshots/unsafe_libopus__celt__cwrs__test__pvq_u_table.snap create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_cwrs32.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_dft.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_entropy.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_laplace.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_mathops.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_mdct.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_rotation.rs create mode 100644 vendor/unsafe-libopus/src/celt/tests/test_unit_types.rs create mode 100644 vendor/unsafe-libopus/src/celt/vq.rs create mode 100644 vendor/unsafe-libopus/src/externs.rs create mode 100644 vendor/unsafe-libopus/src/lib.rs create mode 100644 vendor/unsafe-libopus/src/silk/A2NLSF.rs create mode 100644 vendor/unsafe-libopus/src/silk/CNG.rs create mode 100644 vendor/unsafe-libopus/src/silk/HP_variable_cutoff.rs create mode 100644 vendor/unsafe-libopus/src/silk/Inlines.rs create mode 100644 vendor/unsafe-libopus/src/silk/LPC_analysis_filter.rs create mode 100644 vendor/unsafe-libopus/src/silk/LPC_fit.rs create mode 100644 vendor/unsafe-libopus/src/silk/LPC_inv_pred_gain.rs create mode 100644 vendor/unsafe-libopus/src/silk/LP_variable_cutoff.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF2A.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_VQ.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_VQ_weights_laroia.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_decode.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_del_dec_quant.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_encode.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_stabilize.rs create mode 100644 vendor/unsafe-libopus/src/silk/NLSF_unpack.rs create mode 100644 vendor/unsafe-libopus/src/silk/NSQ.rs create mode 100644 vendor/unsafe-libopus/src/silk/NSQ_del_dec.rs create mode 100644 vendor/unsafe-libopus/src/silk/PLC.rs create mode 100644 vendor/unsafe-libopus/src/silk/SigProc_FIX.rs create mode 100644 vendor/unsafe-libopus/src/silk/VAD.rs create mode 100644 vendor/unsafe-libopus/src/silk/VQ_WMat_EC.rs create mode 100644 vendor/unsafe-libopus/src/silk/ana_filt_bank_1.rs create mode 100644 vendor/unsafe-libopus/src/silk/biquad_alt.rs create mode 100644 vendor/unsafe-libopus/src/silk/bwexpander.rs create mode 100644 vendor/unsafe-libopus/src/silk/bwexpander_32.rs create mode 100644 vendor/unsafe-libopus/src/silk/check_control_input.rs create mode 100644 vendor/unsafe-libopus/src/silk/code_signs.rs create mode 100644 vendor/unsafe-libopus/src/silk/control_SNR.rs create mode 100644 vendor/unsafe-libopus/src/silk/control_audio_bandwidth.rs create mode 100644 vendor/unsafe-libopus/src/silk/control_codec.rs create mode 100644 vendor/unsafe-libopus/src/silk/debug.rs create mode 100644 vendor/unsafe-libopus/src/silk/dec_API.rs create mode 100644 vendor/unsafe-libopus/src/silk/decode_core.rs create mode 100644 vendor/unsafe-libopus/src/silk/decode_frame.rs create mode 100644 vendor/unsafe-libopus/src/silk/decode_indices.rs create mode 100644 vendor/unsafe-libopus/src/silk/decode_parameters.rs create mode 100644 vendor/unsafe-libopus/src/silk/decode_pitch.rs create mode 100644 vendor/unsafe-libopus/src/silk/decode_pulses.rs create mode 100644 vendor/unsafe-libopus/src/silk/decoder_set_fs.rs create mode 100644 vendor/unsafe-libopus/src/silk/define.rs create mode 100644 vendor/unsafe-libopus/src/silk/enc_API.rs create mode 100644 vendor/unsafe-libopus/src/silk/encode_indices.rs create mode 100644 vendor/unsafe-libopus/src/silk/encode_pulses.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/LPC_analysis_filter_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/LTP_analysis_filter_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/LTP_scale_ctrl_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/apply_sine_window_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/autocorrelation_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/burg_modified_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/bwexpander_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/corrMatrix_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/encode_frame_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/energy_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/find_LPC_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/find_LTP_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/find_pitch_lags_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/find_pred_coefs_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/inner_product_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/k2a_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/noise_shape_analysis_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/pitch_analysis_core_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/process_gains_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/residual_energy_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/scale_copy_vector_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/scale_vector_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/schur_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/sort_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/structs_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/warped_autocorrelation_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/float/wrappers_FLP.rs create mode 100644 vendor/unsafe-libopus/src/silk/gain_quant.rs create mode 100644 vendor/unsafe-libopus/src/silk/init_decoder.rs create mode 100644 vendor/unsafe-libopus/src/silk/init_encoder.rs create mode 100644 vendor/unsafe-libopus/src/silk/inner_prod_aligned.rs create mode 100644 vendor/unsafe-libopus/src/silk/interpolate.rs create mode 100644 vendor/unsafe-libopus/src/silk/lin2log.rs create mode 100644 vendor/unsafe-libopus/src/silk/log2lin.rs create mode 100644 vendor/unsafe-libopus/src/silk/macros.rs create mode 100644 vendor/unsafe-libopus/src/silk/mathops.rs create mode 100644 vendor/unsafe-libopus/src/silk/pitch_est_tables.rs create mode 100644 vendor/unsafe-libopus/src/silk/process_NLSFs.rs create mode 100644 vendor/unsafe-libopus/src/silk/quant_LTP_gains.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/ar2.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/down2.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/down2_3.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/down_fir.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/iir_fir.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/mod.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/rom.rs create mode 100644 vendor/unsafe-libopus/src/silk/resampler/up2_hq.rs create mode 100644 vendor/unsafe-libopus/src/silk/shell_coder.rs create mode 100644 vendor/unsafe-libopus/src/silk/sigm_Q15.rs create mode 100644 vendor/unsafe-libopus/src/silk/sort.rs create mode 100644 vendor/unsafe-libopus/src/silk/stereo_LR_to_MS.rs create mode 100644 vendor/unsafe-libopus/src/silk/stereo_MS_to_LR.rs create mode 100644 vendor/unsafe-libopus/src/silk/stereo_decode_pred.rs create mode 100644 vendor/unsafe-libopus/src/silk/stereo_encode_pred.rs create mode 100644 vendor/unsafe-libopus/src/silk/stereo_find_predictor.rs create mode 100644 vendor/unsafe-libopus/src/silk/stereo_quant_pred.rs create mode 100644 vendor/unsafe-libopus/src/silk/structs.rs create mode 100644 vendor/unsafe-libopus/src/silk/sum_sqr_shift.rs create mode 100644 vendor/unsafe-libopus/src/silk/table_LSF_cos.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_LTP.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_NLSF_CB_NB_MB.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_NLSF_CB_WB.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_gain.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_other.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_pitch_lag.rs create mode 100644 vendor/unsafe-libopus/src/silk/tables_pulses_per_block.rs create mode 100644 vendor/unsafe-libopus/src/silk/tests/test_unit_LPC_inv_pred_gain.rs create mode 100644 vendor/unsafe-libopus/src/src/analysis.rs create mode 100644 vendor/unsafe-libopus/src/src/mapping_matrix.rs create mode 100644 vendor/unsafe-libopus/src/src/mlp.rs create mode 100644 vendor/unsafe-libopus/src/src/mlp_data.rs create mode 100644 vendor/unsafe-libopus/src/src/opus.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_decoder.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_defines.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_encoder.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_multistream.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_multistream_decoder.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_multistream_encoder.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_private.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_projection_decoder.rs create mode 100644 vendor/unsafe-libopus/src/src/opus_projection_encoder.rs create mode 100644 vendor/unsafe-libopus/src/src/repacketizer.rs create mode 100644 vendor/unsafe-libopus/src/varargs.rs diff --git a/Cargo.lock b/Cargo.lock index 717f58f8..0046703f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11179,8 +11179,6 @@ dependencies = [ [[package]] name = "unsafe-libopus" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c757408e7256c910343c7b215c8c8b878948630eecc774baabcca0972376eb73" dependencies = [ "arrayref", "num-complex", diff --git a/Cargo.toml b/Cargo.toml index eeb879c1..8532d17d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,13 @@ debug-assertions = false # It can go when presage can move past libsignal v0.97: that waits on davey, whose MLS stack # pins hax-lib 0.3.6 where libsignal v0.98 wants 0.3.7. [patch.crates-io] +# unsafe-libopus 0.2.0 with one fix (vendor/unsafe-libopus, src/silk/PLC.rs and src/silk/CNG.rs, +# marked "tinyclient patch"): c2rust expanded `silk_SAT16`'s lower bound, `(opus_int16)0x8000`, as +# +32768 and dropped the cast, so every sample SILK concealment and comfort noise made was pinned +# to full scale. Concealing a lost packet after a speech-mode (SILK or hybrid) one banged, and +# mediad played a pitch loop instead, which is the "underwater" voice. libopus 1.3.1's +# silk/PLC.c:374 and silk/CNG.c:176 are the reference. Drop this when a release fixes it. +unsafe-libopus = { path = "vendor/unsafe-libopus" } # gpui_ce_wgpu 0.3.0 with one fix (vendor/gpui_ce_wgpu, `WgpuRenderer::destroy`, marked "tinyclient # patch"): it dropped the GPU resources but left the surface marked configured, so the next frame # after an Android app went to the background panicked ("GPU resources not available") and the diff --git a/crates/mediad/src/jitter.rs b/crates/mediad/src/jitter.rs index a7c71e5d..2dc92a26 100644 --- a/crates/mediad/src/jitter.rs +++ b/crates/mediad/src/jitter.rs @@ -11,10 +11,11 @@ const START: usize = 3; /// The least and most ever held: 40 and 200 ms. const LEAST: usize = 2; const MOST: usize = 10; -/// Ticks the jitter must stay under what is held before one packet less is held: 5 s. It takes -/// that long for a passing lull to prove itself, and a depth that follows every lull goes up and -/// down with it. -const RELEASE: u32 = 250; +/// Ticks the jitter must stay under what is held before one packet less is held: 3 s. The +/// spread it is aimed by already remembers the last 10 s, so this only keeps the depth from +/// hunting, which would change the delay of every other sentence; what a step down gives back, +/// squeezing speech gives back unheard. +const RELEASE: u32 = 150; /// Packets over which the shallowest the queue got shows what is spare: half a second. A burst /// arriving together is not spare; what has been sitting there the whole time is. const WATCH: u32 = 25; @@ -144,13 +145,20 @@ impl Jitter { } } - /// The sender's jitter as measured now, once a tick. RFC 3550's figure is an average; a - /// packet lands up to about three times that behind, and then waits for the next tick. What - /// is held goes up the moment that asks for more, and comes down one packet at a time. - pub fn aim(&mut self, jitter_ms: u32) { - let wanted = (jitter_ms as usize * 3 + 20).div_ceil(20).clamp(LEAST, MOST); - if wanted >= self.target { - self.target = wanted; + /// The sender's jitter as measured now, once a tick: RFC 3550's average, and the spread of + /// its recent packets' delays (`Arrivals::spread_ms`), how late one in a hundred came. A + /// packet lands up to about three times the average behind, and the spread says how much + /// further the stragglers do, where Wi-Fi puts them; either way it then waits for the next + /// tick. What is held goes up the moment that asks for more, and comes down one packet at a + /// time. + pub fn aim(&mut self, jitter_ms: u32, spread_ms: u32) { + let wanted_ms = (jitter_ms as usize * 3 + 20).max(spread_ms as usize + 20); + let wanted = wanted_ms.div_ceil(20).clamp(LEAST, MOST); + // Calm only when one packet less would hold it with 10 ms to spare: a need that sits on + // a packet's edge would otherwise step the depth down and straight back up. + let fits_less = wanted_ms + 10 <= (self.target - 1) * 20; + if wanted >= self.target || !fits_less { + self.target = self.target.max(wanted); self.calm = 0; } else if self.due.is_some() { self.calm += 1; @@ -543,25 +551,25 @@ mod tests { fn what_is_held_rises_at_once_and_falls_a_packet_at_a_time() { let mut jitter = Jitter::default(); assert_eq!(jitter.target(), START); - jitter.aim(30); + jitter.aim(30, 0); assert_eq!(jitter.target(), 6, "90 ms of lateness and a tick"); - jitter.aim(500); + jitter.aim(500, 0); assert_eq!(jitter.target(), MOST, "never over 200 ms"); // Not playing: nothing is known yet that says it can come down. for _ in 0..RELEASE * 2 { - jitter.aim(0); + jitter.aim(0, 0); } assert_eq!(jitter.target(), MOST); fill(&mut jitter, &(0..12).collect::>()); assert!(matches!(jitter.pop(), Pop::Packet(_))); for _ in 0..RELEASE - 1 { - jitter.aim(0); + jitter.aim(0, 0); } assert_eq!(jitter.target(), MOST, "still proving itself"); - jitter.aim(0); + jitter.aim(0, 0); assert_eq!(jitter.target(), MOST - 1); for _ in 0..RELEASE * 20 { - jitter.aim(0); + jitter.aim(0, 0); } assert_eq!(jitter.target(), LEAST, "never under 40 ms"); } @@ -569,7 +577,7 @@ mod tests { #[test] fn a_spurt_fills_to_what_the_jitter_asks_for() { let mut jitter = Jitter::default(); - jitter.aim(30); + jitter.aim(30, 0); fill(&mut jitter, &[1, 2, 3, 4, 5]); assert_eq!(jitter.pop(), Pop::Empty, "60 ms is not enough here"); fill(&mut jitter, &[6]); @@ -592,7 +600,7 @@ mod tests { let wobble = u64::from(seed >> 16) * 60 / 65_536; arrivals.arrived(u32::from(n) * 960, start + Duration::from_millis(u64::from(n) * 20 + wobble)); jitter.insert(n, packet(n)); - jitter.aim(arrivals.ms()); + jitter.aim(arrivals.ms(), arrivals.spread_ms()); jitter.pop(); depths.push(jitter.target()); } diff --git a/crates/mediad/src/lib.rs b/crates/mediad/src/lib.rs index 8ccc3c0f..856bb3dd 100644 --- a/crates/mediad/src/lib.rs +++ b/crates/mediad/src/lib.rs @@ -39,6 +39,7 @@ pub mod jitter; pub mod media; pub mod ogg; pub mod opus; +pub mod pace; pub mod picture; pub mod platform; pub mod out; diff --git a/crates/mediad/src/main.rs b/crates/mediad/src/main.rs index 484e0d71..36b40e39 100644 --- a/crates/mediad/src/main.rs +++ b/crates/mediad/src/main.rs @@ -36,6 +36,17 @@ fn main() -> ExitCode { return ExitCode::SUCCESS; } // The lab's missed-frame driver. A build without this opens the audio engine below and stays up. + // The lab's voice-playout driver. A build without this opens the audio engine below and + // stays up. + if env::var("TINYCLIENT_PROVE").ok().as_deref() == Some("voice-playout") { + if let Err(err) = mediad::media::prove_voice_playout() { + eprintln!("voice-playout: {err}"); + return ExitCode::from(1); + } + // What the driver looks for: any mediad exits 0 once its input closes. + eprintln!("voice-playout: proved"); + return ExitCode::SUCCESS; + } if env::var("TINYCLIENT_PROVE").ok().as_deref() == Some("missed-frame") { if let Err(err) = mediad::media::prove_missed_frame() { eprintln!("missed-frame: {err}"); diff --git a/crates/mediad/src/media.rs b/crates/mediad/src/media.rs index 0712ad28..da8d33f3 100644 --- a/crates/mediad/src/media.rs +++ b/crates/mediad/src/media.rs @@ -12,6 +12,7 @@ use crate::stats::{Arrivals, Counts, Meter}; use crate::dave::{Dave, Outgoing}; use crate::jitter::{Jitter, Pop}; use crate::opus::{Decoder, Encoder, MAX_FRAME}; +use crate::pace; use crate::permission::{microphone, Microphone}; use crate::discord_video; use crate::rtp::{Cipher, Sender, PAYLOAD_TYPE, SILENCE}; @@ -103,6 +104,53 @@ pub(crate) struct Stream { pub(crate) arrivals: Arrivals, /// The running counts as the connection meter last had them. reported: Counts, + /// What the playout did, over the call and as the log last had it. + pub(crate) playout: Playout, + logged: Playout, + /// Ticks since the log last said; and how many ticks in a row, now, something has stood in + /// for packets in mid-speech. + since_logged: u32, + standing_in: u32, +} + +/// Ticks between log lines about one voice's playout: 10 s. A line is written only when +/// something had to be made up in that time. +const PLAYOUT_LOG: u32 = 500; + +/// What one voice's playout did. Each of these is heard, one way or another: the log says how +/// often, so a call that sounded wrong can be lined up with what happened. +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] +pub struct Playout { + /// Frames played as they came. + pub played: u64, + /// Ticks in mid-speech that the packet due was not there yet (late, or a reorder wait), + /// and libopus carried the voice on. + pub waited: u64, + /// Frames lost and made up by libopus, and by the pitch loop because libopus would not. + pub concealed: u64, + pub looped: u64, + /// Frames played a pitch period longer, so the buffer did not run dry; shorter, to give back + /// delay in mid-speech; and quiet frames dropped whole for the same. + pub stretched: u64, + pub squeezed: u64, + pub shed: u64, + /// The longest anything stood in for packets in a row, in ticks. + pub longest: u32, +} + +impl Playout { + fn since(&self, then: &Playout) -> Playout { + Playout { + played: self.played - then.played, + waited: self.waited - then.waited, + concealed: self.concealed - then.concealed, + looped: self.looped - then.looped, + stretched: self.stretched - then.stretched, + squeezed: self.squeezed - then.squeezed, + shed: self.shed - then.shed, + longest: self.longest, + } + } } impl Stream { @@ -129,6 +177,10 @@ impl Stream { gain: None, arrivals: Arrivals::default(), reported: Counts::default(), + playout: Playout::default(), + logged: Playout::default(), + since_logged: 0, + standing_in: 0, }) } @@ -164,7 +216,8 @@ impl Stream { /// log. pub(crate) fn pull(&mut self, who: &dyn std::fmt::Display) -> Option> { let mut pcm = [0i16; MAX_FRAME * CHANNELS]; - self.jitter.aim(self.arrivals.ms()); + self.jitter.aim(self.arrivals.ms(), self.arrivals.spread_ms()); + let mut stood_in = false; while self.pcm.len() < FRAME_SAMPLES { let decoded = match self.jitter.pop() { Pop::Packet(packet) => { @@ -173,24 +226,38 @@ impl Stream { self.jitter.deepen(); } let decoded = self.played(&packet, &mut pcm); - // More is queued than this voice calls for. A quiet frame can go: nothing - // is played faster, so nothing warbles, and the delay is gone. + // More is queued than this voice calls for. A quiet frame can go whole. if decoded.is_some() && self.jitter.hushed && self.jitter.shed() { + self.playout.shed += 1; continue; } + if let Some(samples) = decoded { + self.playout.played += 1; + if self.paced(&pcm[..samples * CHANNELS]) { + continue; + } + } decoded } - // Not a loss yet. Pitch carries the voice; the decoder stays put so the packet - // after a real gap can still rebuild it. + // Not here yet, with a later packet already queued. In mid-speech libopus carries + // the voice on; the packet, when it comes, decodes after that as after a loss. + Pop::Hold if !self.jitter.hushed => { + stood_in = true; + self.playout.waited += 1; + Some(self.decoder.stand_in(FRAME, &mut pcm)) + } Pop::Hold => Some(self.decoder.bridge(FRAME, &mut pcm)), Pop::Spurt(packet) => { // Cut off in mid-speech and never resumed: what came between is gone. if std::mem::take(&mut self.stalled) { self.decoder.missed(2); } - self.played(&packet, &mut pcm) + let decoded = self.played(&packet, &mut pcm); + self.playout.played += u64::from(decoded.is_some()); + decoded } Pop::Lost(frames) => { + stood_in = true; self.decoder.missed(frames - 1); // The packet after the hole may carry a copy of what was lost. let rebuilt = self.jitter.next().and_then(|next| self.decoder.recover(next, &mut pcm)); @@ -198,10 +265,17 @@ impl Stream { rebuilt.or_else(|| self.decoder.decode(None, FRAME, &mut pcm)) } Pop::Late => { - // After the quiet end of a sentence this is nothing at all; while someone - // is speaking, a stall the next packet may end. - self.stalled |= !self.jitter.hushed; - Some(self.decoder.late(FRAME, &mut pcm)) + // After the quiet end of a sentence this is nothing at all, and the voice + // fades out. While someone is speaking it is a stall the next packet may + // end, and libopus carries the voice on meanwhile. + if self.jitter.hushed { + Some(self.decoder.late(FRAME, &mut pcm)) + } else { + stood_in = true; + self.stalled = true; + self.playout.waited += 1; + Some(self.decoder.stand_in(FRAME, &mut pcm)) + } } Pop::Empty => break, }; @@ -215,9 +289,69 @@ impl Stream { } } } + self.standing_in = if stood_in { self.standing_in + 1 } else { 0 }; + self.playout.longest = self.playout.longest.max(self.standing_in); + // The decoder counts every frame libopus made up; those for a packet only waited for + // are counted apart. + self.playout.concealed = self.decoder.concealed.saturating_sub(self.playout.waited); + self.playout.looped = self.decoder.looped; + self.since_logged += 1; + if self.since_logged >= PLAYOUT_LOG { + self.log_playout(who, false); + } (self.pcm.len() >= FRAME_SAMPLES).then(|| self.pcm.drain(..FRAME_SAMPLES).collect()) } + /// Plays a frame just decoded a pitch period longer while the buffer is short of where it + /// should be, and shorter while it holds more than it needs in mid-speech. Whether it did + /// either: the frame is in `pcm` then. + fn paced(&mut self, frame: &[i16]) -> bool { + let queued = self.jitter.held() * FRAME_SAMPLES + self.pcm.len(); + let steady = self.jitter.target().saturating_sub(1) * FRAME_SAMPLES; + let paced = if queued < steady { + pace::expand(frame).inspect(|_| self.playout.stretched += 1) + } else if !self.jitter.hushed && queued > steady + 2 * FRAME_SAMPLES { + pace::accelerate(frame).inspect(|_| self.playout.squeezed += 1) + } else { + None + }; + let Some(paced) = paced else { + return false; + }; + self.pcm.extend(paced); + true + } + + /// A line about what this voice's playout did: over the last 10 s, when anything had to be + /// made up in them, or over the whole call (`whole`), always. + pub(crate) fn log_playout(&mut self, who: &dyn std::fmt::Display, whole: bool) { + let done = if whole { self.playout } else { self.playout.since(&self.logged) }; + self.since_logged = 0; + self.logged = self.playout; + self.playout.longest = 0; + if !whole && done.waited + done.concealed + done.looped == 0 { + return; + } + tracing::warn!( + "mediad: {who} playout, {}: {} played, {} waited for, {} lost made up by libopus and {} by the pitch loop, {} stretched, {} squeezed, {} quiet dropped; longest stand-in {} ms; holding {} ms (spread {} ms, jitter {} ms); over the call {} lost ({} rebuilt), {} late", + if whole { "call" } else { "last 10 s" }, + done.played, + done.waited, + done.concealed, + done.looped, + done.stretched, + done.squeezed, + done.shed, + done.longest * 20, + self.jitter.target() * 20, + self.arrivals.spread_ms(), + self.arrivals.ms(), + self.jitter.lost, + self.rebuilt, + self.jitter.late, + ); + } + /// Decodes a packet whose turn it is, and notes how loud it was. fn played(&mut self, packet: &[u8], pcm: &mut [i16]) -> Option { let samples = self.decoder.decode(Some(packet), 0, pcm)?; @@ -345,6 +479,100 @@ impl Gate { } } +/// What one voice's playout did over [`wifi_call`]. +#[derive(Debug)] +pub struct WifiCall { + pub playout: Playout, + pub lost: u64, + pub rebuilt: u64, + /// The loudest sample played, and how much was queued (packets) against what the buffer aims + /// for at the end, after speech went on through a stall. + pub peak: u16, + pub held: usize, + pub target: usize, +} + +/// Three seconds of a voiced vowel at 24 kbit/s (a speech-mode, SILK or hybrid, stream) through +/// one receive stream, arriving as over Wi-Fi: each packet up to 8 ms late, one in fifty 45 ms +/// late, a 250 ms stall at 1.5 s that then delivers its backlog at once, one in 37 lost, and two +/// in a row once, which no in-band copy can rebuild. +/// Ticks are 20 ms; each takes what has arrived by then and plays a frame. +pub fn wifi_call() -> Option { + const FRAMES: usize = 150; + let mut encoder = Encoder::at(24_000)?; + let mut seed = 0x5eed_u32; + let mut sent = Vec::new(); + for f in 0..FRAMES { + let mut pcm = [0i16; FRAME_SAMPLES]; + for (n, pair) in pcm.as_chunks_mut::().0.iter_mut().enumerate() { + let t = (f * FRAME + n) as f64 / 48_000.; + let swell = 0.6 + 0.4 * (t * 3. * std::f64::consts::TAU).sin(); + let voice: f64 = (1..=10).map(|k| (t * 140. * k as f64 * std::f64::consts::TAU).sin() / k as f64).sum(); + pair.fill((voice * swell * 4_000.) as i16); + } + let mut packet = [0u8; 1275]; + let len = encoder.encode(&pcm, &mut packet)?; + seed = seed.wrapping_mul(1_664_525).wrapping_add(1_013_904_223); + let mut due = f as u64 * 20 + u64::from(seed >> 16) % 9; + if f % 50 == 17 { + due += 45; + } + if (75..88).contains(&f) { + // Held up behind a stall until 1.75 s, then all at once. + due = due.max(1_750); + } + if f % 37 != 20 && !(100..102).contains(&f) { + sent.push((due, f as u16, packet[..len].to_vec())); + } + } + sent.sort_by_key(|(due, sequence, _)| (*due, *sequence)); + let mut stream = Stream::new()?; + let start = Instant::now(); + let mut peak = 0u16; + let mut next = 0; + for tick in 0..FRAMES as u64 + 40 { + let now = tick * 20; + while next < sent.len() && sent[next].0 <= now { + let (due, sequence, packet) = &sent[next]; + stream.arrivals.arrived(u32::from(*sequence) * 960, start + Duration::from_millis(*due)); + stream.jitter.insert(*sequence, packet.clone()); + next += 1; + } + if let Some(frame) = stream.pull(&"wifi") { + peak = peak.max(frame.iter().map(|sample| sample.unsigned_abs()).max().unwrap_or(0)); + } + if tick == FRAMES as u64 - 5 { + // Speech has gone on unbroken since the stall: what it left queued should be gone. + let (held, target) = (stream.jitter.held(), stream.jitter.target()); + return Some(WifiCall { playout: stream.playout, lost: stream.jitter.lost, rebuilt: stream.rebuilt, peak, held, target }); + } + } + None +} + +/// The lab's voice-playout driver: a Wi-Fi call's voice is carried on by libopus and paced, +/// never looped, saturated, or left behind by a stall. +pub fn prove_voice_playout() -> Result<(), String> { + let call = wifi_call().ok_or("the codec did not start")?; + let fail = |what: &str| Err(format!("{what}: {call:?}")); + if call.playout.looped > 0 { + return fail("the pitch loop stood in for a lost packet"); + } + if call.peak >= 30_000 { + return fail("a concealed frame saturated"); + } + if call.lost == 0 || call.playout.concealed == 0 { + return fail("nothing was concealed, so nothing was proved"); + } + if call.playout.waited > 16 { + return fail("the buffer ran dry on the stragglers, not only on the stall"); + } + if call.held > call.target + 1 { + return fail("the stall's backlog was still queued in mid-speech"); + } + Ok(()) +} + /// A missed microphone tick is a hole, not a quiet frame, so it does not spend the hangover. pub fn prove_missed_frame() -> Result<(), &'static str> { let mut gate = Gate::default(); @@ -542,6 +770,10 @@ impl Loop { } if let Some(frame) = frame { stream.heard |= frame != SILENCE; + if frame == SILENCE { + // Discord's five silence frames before a pause: how long it lasts is not lateness. + stream.arrivals.paused(); + } stream.jitter.insert(packet.sequence, frame); } } @@ -712,12 +944,8 @@ impl Loop { } self.pictures.finish(); finish_cue(&self.setup.controls, &mut self.cue, &mut self.setup.audio); - for (ssrc, stream) in &self.streams { - let (jitter, rebuilt) = (&stream.jitter, stream.rebuilt); - tracing::warn!( - "mediad: ssrc {ssrc}: {} lost ({rebuilt} rebuilt), {} late", - jitter.lost, jitter.late - ); + for (ssrc, stream) in &mut self.streams { + stream.log_playout(&format_args!("ssrc {ssrc}"), true); } sign_off(&self.setup.audio); } @@ -1446,10 +1674,17 @@ mod receive_tests { assert_eq!(stream.gaps, 0); } - /// Speech and pauses, with 60 ms too many queued, as a stall leaves it. The extra goes in - /// the first quiet frames, and not one frame of the speech goes with it. #[test] - fn a_backlog_drains_through_quiet_frames_and_never_through_speech() { + fn a_wifi_call_is_carried_on_by_libopus_and_paced_through_a_stall() { + eprintln!("{:?}", wifi_call()); + prove_voice_playout().unwrap(); + } + + /// Speech and pauses, with 60 ms too many queued, as a stall leaves it. The speech plays a + /// pitch period faster now and then until the extra is gone, and not one frame of it is + /// dropped; the quiet frames after it go whole. + #[test] + fn a_backlog_drains_through_speech_played_faster_and_never_dropped() { let mut encoder = Encoder::voice().unwrap(); let (speech, mut spare) = (tone_packets(60), Vec::new()); for _ in 0..60 { @@ -1467,7 +1702,9 @@ mod receive_tests { stream.jitter.insert(n, packet); played += usize::from(stream.pull(&"backlog").is_some()); if n == 59 { - assert_eq!(stream.jitter.held(), 6, "speech is never dropped"); + assert_eq!(stream.playout.shed, 0, "speech is never dropped"); + assert!(stream.playout.squeezed > 0, "speech is played faster"); + assert!(stream.jitter.held() < 6, "{} still queued at the end of the speech", stream.jitter.held()); } } assert_eq!(played, 114); diff --git a/crates/mediad/src/opus.rs b/crates/mediad/src/opus.rs index e9fdf0f9..9aabbba3 100644 --- a/crates/mediad/src/opus.rs +++ b/crates/mediad/src/opus.rs @@ -207,8 +207,6 @@ impl Drop for Encoder { pub struct Decoder { state: *mut OpusDecoder, - /// The last packet was CELT-only, the mode whose concealment libopus is trusted with here. - celt: bool, /// A packet has been decoded: the decoder has a mode, and a last sample to fade from. started: bool, /// The last frame that came out, for concealing a loss ourselves. @@ -221,6 +219,12 @@ pub struct Decoder { cursor: usize, gain: f32, concealing: bool, + /// Frames libopus made up, for a loss or a packet not here yet; and frames the pitch loop + /// made up because libopus would not. Read for the log. + pub concealed: u64, + pub looped: u64, + /// Ticks in a row [`Decoder::stand_in`] has carried the voice on for a packet not here yet. + standing: u32, } unsafe impl Send for Decoder {} @@ -232,7 +236,6 @@ impl Decoder { let state = unsafe { opus_decoder_create(RATE as i32, CHANNELS as i32, &mut error) }; (!state.is_null() && error == 0).then_some(Decoder { state, - celt: false, started: false, last: Vec::new(), misses: 0, @@ -240,6 +243,9 @@ impl Decoder { cursor: 0, gain: 0., concealing: false, + concealed: 0, + looped: 0, + standing: 0, }) } @@ -251,31 +257,14 @@ impl Decoder { return Some(self.conceal(lost.min(room), pcm)); }; self.forget(); - // After a SILK or hybrid packet, libopus builds a CELT-only one out of 5 ms of SILK - // packet-loss concealment. A packet from an encoder carries a redundant CELT frame to - // splice there; the fixed silence packet does not, and this build's concealment - // saturates. The mode change resets CELT anyway, so start from a clean state instead. - let celt = packet[0] >> 3 >= 16; - let switched = celt && !self.celt && self.started; - if switched { - // SAFETY: `state` is a live decoder; the request takes no argument. - unsafe { - opus_decoder_ctl!(self.state, OPUS_RESET_STATE); - } - } + // After a SILK or hybrid packet, libopus builds the first CELT-only one out of 5 ms of + // SILK concealment. With the patched library (vendor/unsafe-libopus) that splice is the + // reference's, so a mode switch needs nothing of ours. // SAFETY: `pcm` has room for `room` samples per channel. let decoded = unsafe { opus_decode(self.state, packet.as_ptr(), packet.len() as i32, pcm.as_mut_ptr(), room as i32, 0) }; let samples = usize::try_from(decoded).ok()?; - // The table-of-contents byte's top five bits are the configuration; 16 and up are CELT. - self.celt = celt; self.started = true; - if switched { - // No waveform continues across the switch, so fade this frame in from the sample - // the speech ended on. A step there is the click. - self.start_afresh(&mut pcm[..samples * CHANNELS]); - } else { - self.resume(&mut pcm[..samples * CHANNELS]); - } + self.resume(&mut pcm[..samples * CHANNELS]); Some(samples) } @@ -307,31 +296,24 @@ impl Decoder { samples } - /// `frames` went by that the decoder will never see and no tick stands in for. Whatever it - /// decodes next starts from a clean state, as after that many concealed frames in a row. + /// `frames` went by that the decoder will never see and no tick stands in for. libopus takes + /// the next packet after them as after any loss. pub(crate) fn missed(&mut self, frames: u32) { - if frames > 0 { - self.carry_on(); - self.misses = self.misses.saturating_add(frames); - } + self.misses = self.misses.saturating_add(frames); } - /// Stands in for a lost packet when the one after it cannot rebuild it ([`Decoder::recover`]). - /// After CELT, libopus conceals it. After a SILK or hybrid packet it may not: - /// `unsafe-libopus` 0.2.0 saturates there (a test below holds it to that, so a fixed library - /// is noticed), so the decoder is left untouched and the voice is carried on here instead: - /// the last pitch period of what was heard, repeated from exactly where it left off, fading - /// to silence over 60 ms. Repeating the whole last frame instead jumps at each seam, and - /// that jump is a click every lost packet. + /// Stands in for a lost packet when the one after it cannot rebuild it ([`Decoder::recover`]): + /// libopus conceals it, in every mode. Until the library was patched (vendor/unsafe-libopus) + /// it saturated after a SILK or hybrid packet, and a repeated pitch period stood in for it + /// there: that loop is the voice heard "under water". It is kept only for a decoder that + /// refuses to conceal. fn conceal(&mut self, samples: usize, pcm: &mut [i16]) -> usize { self.misses += 1; - if self.celt { - // SAFETY: a null packet asks for concealment of `samples` per channel, which fit. - let decoded = unsafe { opus_decode(self.state, std::ptr::null(), 0, pcm.as_mut_ptr(), samples as i32, 0) }; - if let Ok(decoded) = usize::try_from(decoded) { - return decoded; - } + if let Some(decoded) = self.plc(samples, pcm) { + self.concealed += 1; + return decoded; } + self.looped += 1; self.carry_on(); let out = &mut pcm[..samples * CHANNELS]; let fall = 1. / (FADE_FRAMES * samples.max(1)) as f32; @@ -342,6 +324,50 @@ impl Decoder { samples } + /// libopus's own concealment of one frame, into `pcm`. `None` when it refused, or before the + /// first packet, when there is nothing to carry on. + fn plc(&mut self, samples: usize, pcm: &mut [i16]) -> Option { + if !self.started || self.concealing { + return None; + } + // SAFETY: a null packet asks for concealment of `samples` per channel, which fit. + let decoded = unsafe { opus_decode(self.state, std::ptr::null(), 0, pcm.as_mut_ptr(), samples as i32, 0) }; + let decoded = usize::try_from(decoded).ok().filter(|&decoded| decoded > 0)?; + self.record(&pcm[..decoded * CHANNELS]); + Some(decoded) + } + + /// A tick in mid-speech whose packet is not here yet, a reorder wait or a late one: libopus + /// carries the voice on, as for a loss, and the packet decodes after it as the one after a + /// loss does. Only after a quiet frame, where nothing is heard either way, does + /// [`Decoder::late`] fade out instead. + /// + /// It fades to silence over 60 ms, as the voice would at the end of a sentence cut short: a + /// packet that has not come by then may never, and libopus would ring on for as long as it + /// is asked. + pub(crate) fn stand_in(&mut self, samples: usize, pcm: &mut [i16]) -> usize { + match self.plc(samples, pcm) { + Some(decoded) => { + self.concealed += 1; + let out = &mut pcm[..decoded * CHANNELS]; + let (from, span) = (self.standing as f32, (FADE_FRAMES * decoded) as f32); + for (n, pair) in out.as_chunks_mut::().0.iter_mut().enumerate() { + let gain = (1. - (from * decoded as f32 + n as f32 + 1.) / span).max(0.); + for sample in pair { + *sample = (f32::from(*sample) * gain) as i16; + } + } + self.standing += 1; + self.record(out); + decoded + } + None => { + self.looped += 1; + self.late(samples, pcm) + } + } + } + /// One tick with nothing to play: a packet running late, or the end of a sentence, and only /// the next packet can tell. Nothing is lost so far, so the decoder stays where the last real /// frame left it and a late packet simply continues it. Meanwhile the voice carries on, @@ -405,6 +431,7 @@ impl Decoder { /// A real frame came out, into `pcm`: crossfaded from the concealment it follows, if any, /// so speaking again after a loss does not click either. fn resume(&mut self, pcm: &mut [i16]) { + self.standing = 0; if self.concealing { let frames = pcm.len() / CHANNELS; let fade = RESUME.min(frames); @@ -421,23 +448,6 @@ impl Decoder { self.record(pcm); } - /// A frame in another mode came out of a decoder that was reset for it: no waveform - /// continues across the switch, so fade it in from the sample the last frame ended on. - /// Stepping from that sample to wherever the new mode starts is the click. - fn start_afresh(&mut self, pcm: &mut [i16]) { - let from = self.ending(); - let frames = pcm.len() / CHANNELS; - let fade = RESUME.min(frames); - for n in 0..fade { - let toward = (n + 1) as f32 / (fade + 1) as f32; - for (channel, sample) in pcm[n * CHANNELS..(n + 1) * CHANNELS].iter_mut().enumerate() { - *sample = (f32::from(from[channel]) * (1. - toward) + f32::from(*sample) * toward) as i16; - } - } - self.concealing = false; - self.record(pcm); - } - /// The sample the last frame ended on: what a frame that does not continue it fades from. fn ending(&self) -> [i16; CHANNELS] { if self.last.len() >= CHANNELS { @@ -741,8 +751,8 @@ mod tests { } /// At 12 kbit/s libopus sends speech-mode (SILK) packets, as a low-bitrate voice channel - /// does. Asking `unsafe-libopus` 0.2.0 to conceal a loss after one returns full-scale - /// samples and leaves the following frames too loud, so `Decoder` conceals those itself. + /// does. A loss after one is concealed at the voice's level, and the frames after it are not + /// too loud: libopus's concealment, now that the library is patched. #[test] fn a_loss_after_a_speech_mode_packet_is_concealed_without_a_bang() { let (mut encoder, mut decoder) = (Encoder::at(12_000).unwrap(), Decoder::new().unwrap()); @@ -756,6 +766,7 @@ mod tests { assert_eq!(concealed, FRAME); let level = peak(&pcm[..FRAME * CHANNELS]); assert!((2000..9_500).contains(&level), "concealment peaks at {level}"); + assert_eq!(decoder.looped, 0, "libopus concealed it, not the pitch loop"); continue; } let decoded = decoder.decode(Some(&packet[..len]), 0, &mut pcm).unwrap(); @@ -776,11 +787,11 @@ mod tests { .collect() } - /// Why `conceal` does not ask libopus after a speech-mode packet. Checked again against - /// `unsafe-libopus` 0.2.0: its concealment there returns full scale, and so does the frame - /// after. When this test fails the library was fixed and the workaround can go. + /// The library itself, below `Decoder`: stock `unsafe-libopus` 0.2.0 returned full scale + /// here, every sample, because c2rust turned `silk_SAT16`'s lower bound into +32768. This + /// holds the patch in vendor/unsafe-libopus to it. #[test] - fn the_library_still_saturates_when_asked_to_conceal_after_a_speech_mode_packet() { + fn the_library_conceals_a_speech_mode_loss_without_saturating() { let packets = encoded(12_000, 8); let mut error = 0; // SAFETY: a decoder of our own, destroyed below; `pcm` has room for the longest frame. @@ -793,7 +804,12 @@ mod tests { assert!(peak(&pcm[..FRAME * CHANNELS]) < 9_000, "the tone peaks at 8000"); let concealed = opus_decode(raw, std::ptr::null(), 0, pcm.as_mut_ptr(), FRAME as i32, 0); assert_eq!(concealed, FRAME as i32); - assert_eq!(peak(&pcm[..FRAME * CHANNELS]), 32_767, "fixed upstream? then drop the workaround"); + let level = peak(&pcm[..FRAME * CHANNELS]); + assert!((1_000..9_000).contains(&level), "concealment peaks at {level}; 32767 is the unpatched library"); + let next = opus_decode(raw, packets[7].as_ptr(), packets[7].len() as i32, pcm.as_mut_ptr(), MAX_FRAME as i32, 0); + assert_eq!(next, FRAME as i32); + let level = peak(&pcm[..FRAME * CHANNELS]); + assert!(level < 9_000, "the frame after the loss peaks at {level}"); opus_decoder_destroy(raw); } } @@ -842,12 +858,10 @@ mod tests { assert!(energy(&pcm[..FRAME * CHANNELS]) < 10.); } - /// The canned silence packet is CELT-only, and the sentence before it is SILK or hybrid. The - /// decoder used to take that for a mode switch and splice 5 ms of SILK concealment onto the - /// front, which this build saturates: a full-scale tick at the start of "silence". It is - /// decoded from a clean state and faded in from the sample the speech ended on instead. - /// A decoder that never heard speech (`the_silence_frame_is_opus_and_decodes_to_quiet`) - /// cannot see this. + /// The canned silence packet is CELT-only, and the sentence before it is SILK or hybrid. + /// libopus splices 5 ms of SILK concealment onto the front of it, which the unpatched library + /// saturated: a full-scale tick at the start of "silence". A decoder that never heard speech + /// (`the_silence_frame_is_opus_and_decodes_to_quiet`) cannot see this. #[test] fn a_silence_packet_after_speech_fades_in_instead_of_banging() { let mut encoder = Encoder::voice().unwrap(); diff --git a/crates/mediad/src/pace.rs b/crates/mediad/src/pace.rs new file mode 100644 index 00000000..c1b544fa --- /dev/null +++ b/crates/mediad/src/pace.rs @@ -0,0 +1,139 @@ +//! A call's voice played a little slower or faster, a frame at a time and at its own pitch, so +//! the jitter buffer can be kept where it should be without running dry or holding on to delay. +//! A frame gets one pitch period longer ([`expand`]) or shorter ([`accelerate`]): two periods +//! that sound alike are crossfaded into three, or into one. Voiced speech repeats itself period +//! by period, so neither is heard; nothing waits for more audio than the frame, so neither adds +//! delay. This is what WebRTC's NetEq calls preemptive expand and accelerate. + +use crate::CHANNELS; + +/// The shortest and longest period looked for: 2.5 and 10 ms (400 down to 100 Hz). Two of the +/// longest fit in a 20 ms frame. +const SHORTEST: usize = 120; +const LONGEST: usize = 480; +/// How alike two periods must be, as a normalized correlation, for one to stand in for the +/// other. Below this the frame is not periodic enough, and it plays as it is. +const ALIKE: f32 = 0.8; +/// Below this level (mean square of the mono mix) a frame is quiet enough that any period will +/// do: nothing in it is heard to repeat. +const QUIET: f32 = 300. * 300.; + +/// The period at which the start of `frame` (interleaved stereo) best repeats, in frames, and +/// whether it is alike enough to stretch or squeeze by. +fn period(frame: &[i16]) -> Option { + let mono: Vec = frame.chunks_exact(CHANNELS).map(|pair| (f32::from(pair[0]) + f32::from(pair[1])) / 2.).collect(); + let longest = LONGEST.min(mono.len() / 2); + if longest < SHORTEST { + return None; + } + let power = mono.iter().map(|s| s * s).sum::() / mono.len() as f32; + if power < QUIET { + return Some(longest); + } + let mut best = (ALIKE, None); + for lag in SHORTEST..=longest { + let (a, b) = (&mono[..lag], &mono[lag..2 * lag]); + let (mut cross, mut ea, mut eb) = (0f32, 0f32, 0f32); + for (x, y) in a.iter().zip(b) { + cross += x * y; + ea += x * x; + eb += y * y; + } + let alike = cross / (ea * eb).sqrt().max(1.); + if alike > best.0 { + best = (alike, Some(lag)); + } + } + best.1 +} + +fn blend(from: i16, to: i16, toward: f32) -> i16 { + (f32::from(from) * (1. - toward) + f32::from(to) * toward).round() as i16 +} + +/// `frame` one pitch period shorter: the first two periods become one that fades from the first +/// into the second, and the rest follows on from where the second ended. `None` when it does +/// not repeat well enough to. +pub fn accelerate(frame: &[i16]) -> Option> { + let lag = period(frame)?; + let mut out = Vec::with_capacity(frame.len() - lag * CHANNELS); + for n in 0..lag { + let toward = (n as f32 + 0.5) / lag as f32; + for channel in 0..CHANNELS { + out.push(blend(frame[n * CHANNELS + channel], frame[(n + lag) * CHANNELS + channel], toward)); + } + } + out.extend_from_slice(&frame[2 * lag * CHANNELS..]); + Some(out) +} + +/// `frame` one pitch period longer: after the first period comes the second fading back into +/// the first, and then the second again and the rest. `None` when it does not repeat well +/// enough to. +pub fn expand(frame: &[i16]) -> Option> { + let lag = period(frame)?; + let mut out = Vec::with_capacity(frame.len() + lag * CHANNELS); + out.extend_from_slice(&frame[..lag * CHANNELS]); + for n in 0..lag { + let toward = (n as f32 + 0.5) / lag as f32; + for channel in 0..CHANNELS { + out.push(blend(frame[(n + lag) * CHANNELS + channel], frame[n * CHANNELS + channel], toward)); + } + } + out.extend_from_slice(&frame[lag * CHANNELS..]); + Some(out) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::FRAME; + + /// A voiced sound: a 200 Hz fundamental with two harmonics, as stereo. + fn voiced(frames: usize, offset: usize) -> Vec { + (offset..offset + frames) + .flat_map(|n| { + let t = n as f32 * std::f32::consts::TAU * 200. / 48_000.; + let sample = (t.sin() * 6000. + (2. * t).sin() * 2500. + (3. * t).sin() * 1200.) as i16; + [sample; 2] + }) + .collect() + } + + fn largest_step(pcm: &[i16]) -> i32 { + pcm.chunks_exact(CHANNELS).collect::>().windows(2).map(|pair| (i32::from(pair[1][0]) - i32::from(pair[0][0])).abs()).max().unwrap() + } + + #[test] + fn a_voiced_frame_grows_and_shrinks_by_whole_periods_without_a_step() { + let frame = voiced(FRAME, 0); + // The steepest the sound itself moves in a sample, and a little room for rounding. + let natural = largest_step(&frame) + 40; + let longer = expand(&frame).expect("periodic"); + let shorter = accelerate(&frame).expect("periodic"); + // 200 Hz is 240 frames a period, and its multiples repeat too. + assert_eq!((longer.len() / CHANNELS - FRAME) % 240, 0, "{}", longer.len() / CHANNELS); + assert_eq!((FRAME - shorter.len() / CHANNELS) % 240, 0, "{}", shorter.len() / CHANNELS); + assert!(largest_step(&longer) <= natural, "expand steps {} against {natural}", largest_step(&longer)); + assert!(largest_step(&shorter) <= natural, "accelerate steps {} against {natural}", largest_step(&shorter)); + // And the frame still ends where it did, so the next one follows on. + assert_eq!(longer[longer.len() - CHANNELS..], frame[frame.len() - CHANNELS..]); + assert_eq!(shorter[shorter.len() - CHANNELS..], frame[frame.len() - CHANNELS..]); + } + + #[test] + fn noise_is_left_alone_and_quiet_goes_either_way() { + let mut seed = 7u32; + let noise: Vec = (0..FRAME * CHANNELS) + .map(|_| { + seed = seed.wrapping_mul(1_664_525).wrapping_add(1_013_904_223); + (seed >> 16) as i16 + }) + .collect(); + assert_eq!(expand(&noise), None); + assert_eq!(accelerate(&noise), None); + let quiet = vec![3i16; FRAME * CHANNELS]; + assert_eq!(expand(&quiet).map(|out| out.len() / CHANNELS), Some(FRAME + LONGEST)); + assert_eq!(accelerate(&quiet).map(|out| out.len() / CHANNELS), Some(FRAME - LONGEST)); + } +} diff --git a/crates/mediad/src/stats.rs b/crates/mediad/src/stats.rs index 882ada8e..33f0090d 100644 --- a/crates/mediad/src/stats.rs +++ b/crates/mediad/src/stats.rs @@ -21,11 +21,35 @@ use crate::RATE; use protocol::{CallPath, CallStats}; use std::time::{Duration, Instant}; -/// RFC 3550 interarrival jitter for one sender, in samples at 48 kHz. +/// Packets whose delay [`Arrivals::spread_ms`] reads: the last 10 s of speech. +const SPREAD_WINDOW: usize = 500; +/// A hole in the RTP time wider than this (100 ms) starts a new spurt: what came after it is +/// not compared with what came before. +const SPURT_BREAK: i64 = 5 * 960; +/// A packet this soon after the one before (2 ms) came in the same lump: a stall let go of its +/// backlog. How late the first of the lump was says it all; counting the rest too would read +/// one stall as a dozen late packets, and a buffer sized for it would hold its 200 ms for 10 s. +const LUMP: Duration = Duration::from_millis(2); + +/// One sender's arrivals, in samples at 48 kHz: RFC 3550's interarrival jitter, an average, and +/// how late its packets come against the earliest of their talk spurt, whose high percentile is +/// what a buffer has to hold to play them all. Wi-Fi delays a packet in one in a hundred by +/// several times the average; a buffer sized from the average runs dry on each of them. #[derive(Debug, Default, Clone)] pub struct Arrivals { last: Option<(Instant, u32)>, jitter: f64, + /// The time of the spurt's first packet, against which every later one is placed, and the + /// least any packet of the spurt took to come against it, in samples. + spurt: Option<(Instant, i64, f64)>, + /// The RTP time last seen, unwrapped. + rtp: Option, + /// The next packet starts a spurt: the sender paused. + paused: bool, + /// When the last packet came. + came: Option, + /// How late each recent packet came against the quickest of its spurt, in samples. + delays: std::collections::VecDeque, } impl Arrivals { @@ -43,11 +67,60 @@ impl Arrivals { if self.last.is_none_or(|(_, stamped)| rtp.wrapping_sub(stamped) as i32 >= 0) { self.last = Some((at, rtp)); } + self.place(rtp, at); + } + + /// The packet just taken was the silence a sender sends before it pauses: whatever comes + /// next starts a new spurt, and how long the pause was is not lateness. + pub fn paused(&mut self) { + self.paused = true; + } + + fn place(&mut self, rtp: u32, at: Instant) { + let unwrapped = self.rtp.map_or(i64::from(rtp), |last| last + i64::from(rtp.wrapping_sub(last as u32) as i32)); + let stepped = self.rtp.map_or(0, |last| unwrapped - last); + self.rtp = Some(self.rtp.map_or(unwrapped, |last| last.max(unwrapped))); + let fresh = std::mem::take(&mut self.paused) || stepped > SPURT_BREAK; + let Some((start, start_rtp, least)) = self.spurt.as_mut().filter(|_| !fresh) else { + self.spurt = Some((at, unwrapped, 0.)); + self.came = Some(at); + return; + }; + let took = at.saturating_duration_since(*start).as_secs_f64() * f64::from(RATE) - (unwrapped - *start_rtp) as f64; + if took > f64::from(RATE) { + // A second behind: the sender's clock stood still through a pause. Start again here. + self.spurt = Some((at, unwrapped, 0.)); + self.came = Some(at); + return; + } + *least = least.min(took); + let lumped = self.came.replace(at).is_some_and(|came| at.saturating_duration_since(came) < LUMP); + if lumped { + return; + } + self.delays.push_back(took - *least); + if self.delays.len() > SPREAD_WINDOW { + self.delays.pop_front(); + } } pub fn ms(&self) -> u32 { (self.jitter * 1000. / f64::from(RATE)).round() as u32 } + + /// How late the latest packets but one in a hundred came, of the last 10 s: what a buffer + /// holds to play 99 of every 100 on time. + pub fn spread_ms(&self) -> u32 { + if self.delays.is_empty() { + return 0; + } + let mut sorted: Vec = self.delays.iter().copied().collect(); + // Past the latest one in a hundred, and never the single latest: in the first seconds + // of a call that would be one stall standing for all of them. + let at = sorted.len().saturating_sub(1 + (sorted.len() / 100).max(1)); + let (_, nth, _) = sorted.select_nth_unstable_by(at, f64::total_cmp); + (*nth * 1000. / f64::from(RATE)).round() as u32 + } } /// One voice's counts since the meter last asked. @@ -242,6 +315,40 @@ mod tests { assert!((8..=11).contains(&shaky.ms()), "{}", shaky.ms()); } + /// One packet in fifty 45 ms late hardly moves the average, and is what the spread is for. + #[test] + fn the_spread_sees_the_stragglers_the_average_does_not() { + let start = Instant::now(); + let mut arrivals = Arrivals::default(); + for n in 0..500u32 { + let late = if n % 50 == 7 { 45 } else { u64::from(n % 3) }; + arrivals.arrived(n * 960, start + Duration::from_millis(u64::from(n) * 20 + late)); + } + assert!(arrivals.ms() <= 4, "the average: {} ms", arrivals.ms()); + assert!((43..=46).contains(&arrivals.spread_ms()), "the spread: {} ms", arrivals.spread_ms()); + } + + /// A pause is not lateness: after the silence before it, or a hole in the RTP time, the next + /// spurt is placed against its own first packet. + #[test] + fn a_pause_does_not_read_as_a_late_packet() { + let start = Instant::now(); + let mut arrivals = Arrivals::default(); + for n in 0..20u32 { + arrivals.arrived(n * 960, start + Duration::from_millis(u64::from(n) * 20)); + } + arrivals.paused(); + // Discord's sequence and time carry on after a pause as if none had been. + for n in 20..40u32 { + arrivals.arrived(n * 960, start + Duration::from_millis(700 + u64::from(n) * 20)); + } + // A Tiny call's RTP time runs on through it. + for n in 100..120u32 { + arrivals.arrived(n * 960, start + Duration::from_millis(1_400 + u64::from(n) * 20)); + } + assert_eq!(arrivals.spread_ms(), 0); + } + #[test] fn a_second_reports_its_own_loss_and_rates() { let mut meter = Meter::new(CallPath::Udp); diff --git a/crates/mediad/src/tiny.rs b/crates/mediad/src/tiny.rs index 52c9d571..5c25285a 100644 --- a/crates/mediad/src/tiny.rs +++ b/crates/mediad/src/tiny.rs @@ -732,6 +732,9 @@ impl Call { // The RTP clock is 48 kHz, as ours. stream.arrivals.arrived(data.time.numer() as u32, data.network_time); stream.heard |= opus[..] != SILENCE[..]; + if opus[..] == SILENCE[..] { + stream.arrivals.paused(); + } if !self.controls.deafened.load(Ordering::Relaxed) { // The SFU writes a fresh sequence, so a lost frame is a hole in the RTP // time and not in `seq_range`. The jitter buffer only sees sequence numbers. @@ -1313,9 +1316,8 @@ impl Call { if let Some(audio) = &mut self.audio { finish_cue(&self.controls, &mut self.cue, audio); } - for (mid, slot) in &self.slots { - let jitter = &slot.stream.jitter; - tracing::warn!("mediad: slot {mid}: {} lost ({} rebuilt), {} late", jitter.lost, slot.stream.rebuilt, jitter.late); + for (mid, slot) in &mut self.slots { + slot.stream.log_playout(&format_args!("slot {mid}"), true); } if let Some(audio) = &self.audio { media::sign_off(audio); diff --git a/e2e/scenarios/voice-playout/drive.linux.sh b/e2e/scenarios/voice-playout/drive.linux.sh new file mode 100644 index 00000000..1eb554a5 --- /dev/null +++ b/e2e/scenarios/voice-playout/drive.linux.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# voice-playout on Linux. The lab runs this with bash while ffmpeg films the display. +set -u +HERE=$(cd "$(dirname "$0")" && pwd) +if command -v python3 >/dev/null 2>&1; then + exec python3 "$HERE/drive.py" +fi +echo "python3 is not on PATH" >&2 +exit 1 diff --git a/e2e/scenarios/voice-playout/drive.macos.sh b/e2e/scenarios/voice-playout/drive.macos.sh new file mode 100644 index 00000000..a63e97c0 --- /dev/null +++ b/e2e/scenarios/voice-playout/drive.macos.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# voice-playout on macOS. The lab runs this with bash while ffmpeg films the display. +set -u +HERE=$(cd "$(dirname "$0")" && pwd) +if command -v python3 >/dev/null 2>&1; then + exec python3 "$HERE/drive.py" +fi +echo "python3 is not on PATH" >&2 +exit 1 diff --git a/e2e/scenarios/voice-playout/drive.py b/e2e/scenarios/voice-playout/drive.py new file mode 100644 index 00000000..72d08f61 --- /dev/null +++ b/e2e/scenarios/voice-playout/drive.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +"""A voice over Wi-Fi: libopus carries it through losses and late packets, and it is paced. + +Starts this build's mediad with TINYCLIENT_PROVE=voice-playout. That build plays three +seconds of speech-mode Opus through a receive stream, arriving as over Wi-Fi (jitter, +stragglers, a 250 ms stall, losses), and exits 0 only when no frame was made up by the +pitch loop, none saturated, the stragglers did not stall it, and the stall's backlog was +given back in mid-speech, saying "voice-playout: proved" on stderr. A build from before +the fix ignores the variable and never says it, so this driver fails there. + +Env from the lab: E2E_OUT, E2E_T0, E2E_APP_DIR. +""" + +import os +import subprocess +import sys +import time + +OUT = os.environ.get("E2E_OUT", "") +T0 = float(os.environ.get("E2E_T0") or time.time()) +APP = os.environ.get("E2E_APP_DIR", "") + +FAILED = False +STEPS = "" + + +def now(): + return time.time() - T0 + + +def step(words, ok): + global FAILED + if not ok: + FAILED = True + line = '{"t": %s, "step": "%s", "ok": %s}' % (round(now(), 1), words.replace('"', "'"), "true" if ok else "false") + print(("[ok] " if ok else "[FAILED] ") + words, flush=True) + if STEPS: + with open(STEPS, "a", encoding="utf-8") as handle: + handle.write(line + "\n") + + +def mediad_bin(app_dir): + name = "mediad.exe" if sys.platform == "win32" else "mediad" + if sys.platform == "darwin" and app_dir.endswith(".app"): + return os.path.join(app_dir, "Contents", "MacOS", "mediad") + return os.path.join(app_dir, name) + + +def main(): + global STEPS + if not OUT or not APP: + print("E2E_OUT and E2E_APP_DIR are required", file=sys.stderr) + return 1 + os.makedirs(OUT, exist_ok=True) + STEPS = os.path.join(OUT, "steps.jsonl") + open(STEPS, "w", encoding="utf-8").close() + binary = mediad_bin(APP) + if not os.path.isfile(binary): + step("mediad is in E2E_APP_DIR", False) + return 1 + + env = os.environ.copy() + env["TINYCLIENT_PROVE"] = "voice-playout" + kwargs = {"env": env, "stdin": subprocess.DEVNULL} + if sys.platform == "win32": + kwargs["creationflags"] = 0x08000000 + with open(os.path.join(OUT, "app.out.log"), "w", encoding="utf-8") as out, open(os.path.join(OUT, "app.err.log"), "w", encoding="utf-8") as err: + kwargs["stdout"] = out + kwargs["stderr"] = err + proc = subprocess.Popen([binary], **kwargs) + try: + code = proc.wait(timeout=45) + except subprocess.TimeoutExpired: + proc.kill() + proc.wait(timeout=5) + code = None + # Any mediad exits 0 once its input closes, so the exit code alone proves nothing: this + # build says so when the proof passed. + with open(os.path.join(OUT, "app.err.log"), encoding="utf-8", errors="replace") as err: + proved = "voice-playout: proved" in err.read() + step("a Wi-Fi voice is concealed by libopus and paced", code == 0 and proved) + return 1 if FAILED else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/e2e/scenarios/voice-playout/drive.windows.ps1 b/e2e/scenarios/voice-playout/drive.windows.ps1 new file mode 100644 index 00000000..0815ec77 --- /dev/null +++ b/e2e/scenarios/voice-playout/drive.windows.ps1 @@ -0,0 +1,17 @@ +# voice-playout on Windows. The lab runs this in the console session it is already filming. +$ErrorActionPreference = 'Stop' +$drive = Join-Path $PSScriptRoot 'drive.py' +if (Get-Command py -ErrorAction SilentlyContinue) { + & py -3 $drive + exit $LASTEXITCODE +} +if (Get-Command python -ErrorAction SilentlyContinue) { + & python $drive + exit $LASTEXITCODE +} +if (Get-Command python3 -ErrorAction SilentlyContinue) { + & python3 $drive + exit $LASTEXITCODE +} +Write-Host 'python is not on PATH (tried py -3, python, python3)' +exit 1 diff --git a/e2e/scenarios/voice-playout/scenario.json b/e2e/scenarios/voice-playout/scenario.json new file mode 100644 index 00000000..c344b0ee --- /dev/null +++ b/e2e/scenarios/voice-playout/scenario.json @@ -0,0 +1,12 @@ +{ + "id": "voice-playout", + "title": "A voice over Wi-Fi is carried on by libopus and paced, never looped or saturated", + "platforms": ["windows", "linux", "macos"], + "not_applicable": { + "android": "The phone proof build does not start desktop mediad. The same playout is in the library the phone links.", + "ios": "The phone proof build does not start desktop mediad. The same playout is in the library the phone links." + }, + "needs": [], + "release": false, + "max_still_seconds": 45 +} diff --git a/vendor/unsafe-libopus/Cargo.toml b/vendor/unsafe-libopus/Cargo.toml new file mode 100644 index 00000000..e403b8ed --- /dev/null +++ b/vendor/unsafe-libopus/Cargo.toml @@ -0,0 +1,48 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "unsafe-libopus" +version = "0.2.0" +authors = ["DCNick3"] +description = "libopus transpiled to rust by c2rust" +readme = "README.md" +license = "BSD-3-Clause" +repository = "https://github.com/DCNick3/unsafe-libopus" + +[profile.release] +debug = 2 + +[dependencies.arrayref] +version = "0.3.7" + +[dependencies.hex] +version = "0.4.3" +optional = true + +[dependencies.num-complex] +version = "0.4.1" + +[dependencies.num-traits] +version = "0.2.16" + +[dev-dependencies.insta] +version = "1.29.0" + +[dev-dependencies.libc] +version = "0.2" + +[dev-dependencies.libc-stdhandle] +version = "0.1.0" + +[features] +ent-dump = ["hex"] diff --git a/vendor/unsafe-libopus/Cargo.toml.orig b/vendor/unsafe-libopus/Cargo.toml.orig new file mode 100644 index 00000000..28685fc4 --- /dev/null +++ b/vendor/unsafe-libopus/Cargo.toml.orig @@ -0,0 +1,44 @@ +[package] +name = "unsafe-libopus" +authors = ["DCNick3"] +version = "0.2.0" +edition = "2021" + +repository = "https://github.com/DCNick3/unsafe-libopus" +description = "libopus transpiled to rust by c2rust" + +license = "BSD-3-Clause" + +[workspace] +members = [ + "upstream-libopus", + "unsafe-libopus-tools", +] + +[profile.release] +debug = true + +[dependencies] +# for complex numbers impl +num-traits = "0.2.16" +num-complex = "0.4.1" + +# for slicing arrays to other arrays +arrayref = "0.3.7" + +# for dumping data in ent-dump +hex = { version = "0.4.3", optional = true } + +[dev-dependencies] +# some translated tests haven't been rewritten not to use libc yet +libc = "0.2" +libc-stdhandle = "0.1.0" + +insta = "1.29.0" + +[features] +# dumps calls to entropy coder to console for easier upstream divergence debugging +# (it's not _only_ entropy coder actually, there are some additional prints where it was found necessary) +ent-dump = [ + "hex" +] diff --git a/vendor/unsafe-libopus/LICENSE b/vendor/unsafe-libopus/LICENSE new file mode 100644 index 00000000..d3c8eb6c --- /dev/null +++ b/vendor/unsafe-libopus/LICENSE @@ -0,0 +1,44 @@ +Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, + Jean-Marc Valin, Timothy B. Terriberry, + CSIRO, Gregory Maxwell, Mark Borgerding, + Erik de Castro Lopo + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Opus is subject to the royalty-free patent licenses which are +specified at: + +Xiph.Org Foundation: +https://datatracker.ietf.org/ipr/1524/ + +Microsoft Corporation: +https://datatracker.ietf.org/ipr/1914/ + +Broadcom Corporation: +https://datatracker.ietf.org/ipr/1526/ \ No newline at end of file diff --git a/vendor/unsafe-libopus/README.md b/vendor/unsafe-libopus/README.md new file mode 100644 index 00000000..60466609 --- /dev/null +++ b/vendor/unsafe-libopus/README.md @@ -0,0 +1,95 @@ +# unsafe-libopus + +This library is [libopus](https://github.com/xiph/opus) 1.3.1 translated from C to unsafe Rust with the assistance +of [c2rust](https://github.com/immunant/c2rust). + +It is called "unsafe" libopus, because it still pretty much has the same shape as the C code and is full of "unsafe". + +This translation still allows you to get rid of C compiler toolchain and use the library in a pure rust environment, +without linker hackery & dynamic linking issues. + +It also may potentially be a starting point for a more idiomatic rust implementation of libopus, though I am not sure if +it is worth the effort. + +## Usage + +You can leverate this library by using a fork of `opus` crate +from [this PR](https://github.com/SpaceManiac/opus-rs/pull/20): + +```toml +[dependencies] +opus = { git = "https://github.com/DCNick3/opus-rs.git", branch = "unsafe-libopus", default-features = false, features = ["unsafe-libopus-backend"] } +``` + +Maybe, this library will have the safe APIs in the future, but for now, it is a (mostly) drop-in replacement for +the `audiopus_sys` crate. + +## Translation technique + +Firstly, the [libopus 1.3.1](https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz) was compiled with the following +commands: + +```bash +CC=clang ./configure --disable-shared --disable-stack-protector --enable-extra-programs --disable-doc --disable-asm --disable-rtcd --disable-intrinsics --disable-dependency-tracking--disable-maintainer-mode --enable-hardening +CC=clang compiledb make -j +``` + +Then, using the resulting `compile_commands.json` file, the C code was transpiled to rust with: + +```bash +c2rust transpile compile_commands.json -o . --overwrite-existing --reorganize-definitions --emit-modules --translate-const-macros --emit-build-files +``` + +The resulting code was then manually reorganized, to remove all duplication of structures & eradicate the use +of `#[no_mangle] extern "C"` functions: they are all linked with rust now and do not have to exported. + +Some other refactorings include: + +- separation of the test binaries from the library as "examples" +- removal of dependencies of libc functions in the library by defining their variants in the library (idea + from [unsafe-libyaml](https://github.com/dtolnay/unsafe-libyaml)) +- removal of dependency on the libc crate by replacing the libc types with concrete rust types (`libc::c_int` -> `i32`, + etc) +- removal of C varargs by replacing them with a custom VarArgs struct, as C variadics are not yet stable in rust. This + turns the `opus_*_ctl` family of functions into macros + +## Performance + +The library was translated without the use of inline assembly, processor intrinsics and runtime CPU detection, so it is +not as fast as the original code right now. The C version with those features is about 20% faster than the rust version +on my machine. + +## Correctness + +This library is tested using (most of) the original tests from the C codebase. They are present in form of rust +integration tests in the `tests` directory. Still not translated are a bunch of unit tests from the C codebase. + +The crux of the testing happens in the `unsafe-libopus-tools/src/bin/run_vectors2.rs` though. +It tests both the decoder and encoder using IETF-published test vectors, +comparing the results with the C implementation of opus 1.3.1 located in `upstream-libopus`. +It does have a small number of patches to make the results more portable. + +The decoder is tested by decoding the test vectors and comparing the results with the C implementation at a +number of output sample rates. +They are checked to match exactly. + +The same is done to the encoder, +running at a number of different bitrates and comparing the encoded results with the C implementation. +Aside from bitrate, no other parameters are changed, which currently is a weak point of the testing. + +Strictly speaking, same encoded results are not required for this to be a valid implementation: the encoder is free to +do a lot of choices, leaving to different quality results. +However, making a codec that is _better_ than the original opus is a non-goal. Therefore, by requiring the exact same +results, we prevent any divergence in the behavior of the encoder. + +## Safety + +Currently, most of the code is unsafe, as it is a direct transpilation of the C code. + +I am currently in the process of slowly refactoring the code to make certain parts of it safe. Previously maintaining +validity was a challenge, but now that there are tests checking the implementation against the C code, it should become +easier. + +## License + +Same as the original libopus, `unsafe-libopus` is licensed under the BSD 3-clause license. diff --git a/vendor/unsafe-libopus/src/celt/bands.rs b/vendor/unsafe-libopus/src/celt/bands.rs new file mode 100644 index 00000000..69aa9bf5 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/bands.rs @@ -0,0 +1,2145 @@ +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub type celt_sig = f32; + pub type celt_norm = f32; + pub type celt_ener = f32; + pub const Q15ONE: f32 = 1.0f32; + pub const NORM_SCALING: f32 = 1.0f32; + pub const EPSILON: f32 = 1e-15f32; +} +pub mod stack_alloc_h { + pub const ALLOC_NONE: i32 = 1; +} +pub mod stddef_h { + pub const NULL: i32 = 0; +} +pub use self::arch_h::{ + celt_ener, celt_norm, celt_sig, opus_val16, opus_val32, EPSILON, NORM_SCALING, Q15ONE, +}; +pub use self::stack_alloc_h::ALLOC_NONE; +pub use self::stddef_h::NULL; +use crate::celt::entcode::{celt_sudiv, celt_udiv, ec_ctx, ec_ctx_saved, ec_tell_frac, BITRES}; +use crate::celt::entdec::{ec_dec_bit_logp, ec_dec_bits, ec_dec_uint, ec_dec_update, ec_decode}; +use crate::celt::entenc::{ec_enc_bit_logp, ec_enc_bits, ec_enc_uint, ec_encode}; +use crate::celt::mathops::{celt_exp2, celt_rsqrt, celt_rsqrt_norm, celt_sqrt, isqrt32}; +use crate::celt::modes::OpusCustomMode; +use crate::celt::pitch::{celt_inner_prod_c, dual_inner_prod_c}; +use crate::celt::quant_bands::eMeans; +use crate::celt::rate::{ + bits2pulses, get_pulses, pulses2bits, QTHETA_OFFSET, QTHETA_OFFSET_TWOPHASE, +}; +use crate::celt::vq::{alg_quant, alg_unquant, renormalise_vector, stereo_itheta}; +use crate::externs::{memcpy, memset}; +use crate::silk::macros::EC_CLZ0; + +pub const SPREAD_NONE: i32 = 0; +pub const SPREAD_LIGHT: i32 = 1; +pub const SPREAD_NORMAL: i32 = 2; +pub const SPREAD_AGGRESSIVE: i32 = 3; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct band_ctx<'a> { + pub encode: i32, + pub resynth: i32, + pub m: *const OpusCustomMode, + pub i: i32, + pub intensity: i32, + pub spread: i32, + pub tf_change: i32, + pub ec: *mut ec_ctx<'a>, + pub remaining_bits: i32, + pub bandE: *const celt_ener, + pub seed: u32, + pub arch: i32, + pub theta_round: i32, + pub disable_inv: i32, + pub avoid_split_noise: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct split_ctx { + pub inv: i32, + pub imid: i32, + pub iside: i32, + pub delta: i32, + pub itheta: i32, + pub qalloc: i32, +} +pub unsafe fn hysteresis_decision( + val: opus_val16, + thresholds: *const opus_val16, + hysteresis: *const opus_val16, + N: i32, + prev: i32, +) -> i32 { + let mut i: i32 = 0; + while i < N { + if val < *thresholds.offset(i as isize) { + break; + } + i += 1; + } + if i > prev && val < *thresholds.offset(prev as isize) + *hysteresis.offset(prev as isize) { + i = prev; + } + if i < prev + && val > *thresholds.offset((prev - 1) as isize) - *hysteresis.offset((prev - 1) as isize) + { + i = prev; + } + return i; +} +pub unsafe fn celt_lcg_rand(seed: u32) -> u32 { + return (1664525_u32).wrapping_mul(seed).wrapping_add(1013904223); +} +pub unsafe fn bitexact_cos(x: i16) -> i16 { + let mut tmp: i32 = 0; + let mut x2: i16 = 0; + tmp = 4096 + x as i32 * x as i32 >> 13; + x2 = tmp as i16; + x2 = (32767 - x2 as i32 + + (16384 + + x2 as i32 + * (-(7651) + + (16384 + + x2 as i32 + * (8277 + (16384 + -(626) as i16 as i32 * x2 as i32 >> 15)) as i16 + as i32 + >> 15)) as i16 as i32 + >> 15)) as i16; + return (1 + x2 as i32) as i16; +} +pub unsafe fn bitexact_log2tan(mut isin: i32, mut icos: i32) -> i32 { + let mut lc: i32 = 0; + let mut ls: i32 = 0; + lc = EC_CLZ0 - (icos as u32).leading_zeros() as i32; + ls = EC_CLZ0 - (isin as u32).leading_zeros() as i32; + icos <<= 15 - lc; + isin <<= 15 - ls; + return (ls - lc) * ((1) << 11) + + (16384 + + isin as i16 as i32 + * ((16384 + isin as i16 as i32 * -(2597) as i16 as i32 >> 15) + 7932) as i16 + as i32 + >> 15) + - (16384 + + icos as i16 as i32 + * ((16384 + icos as i16 as i32 * -(2597) as i16 as i32 >> 15) + 7932) as i16 + as i32 + >> 15); +} +pub unsafe fn compute_band_energies( + m: *const OpusCustomMode, + X: *const celt_sig, + bandE: *mut celt_ener, + end: i32, + C: i32, + LM: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut N: i32 = 0; + let eBands: *const i16 = (*m).eBands; + N = (*m).shortMdctSize << LM; + c = 0; + loop { + i = 0; + while i < end { + let mut sum: opus_val32 = 0.; + sum = 1e-27f32 + + celt_inner_prod_c( + &*X.offset((c * N + ((*eBands.offset(i as isize) as i32) << LM)) as isize), + &*X.offset((c * N + ((*eBands.offset(i as isize) as i32) << LM)) as isize), + (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32) + << LM, + ); + *bandE.offset((i + c * (*m).nbEBands) as isize) = celt_sqrt(sum); + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } +} +pub unsafe fn normalise_bands( + m: *const OpusCustomMode, + freq: *const celt_sig, + X: *mut celt_norm, + bandE: *const celt_ener, + end: i32, + C: i32, + M: i32, +) { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut N: i32 = 0; + let eBands: *const i16 = (*m).eBands; + N = M * (*m).shortMdctSize; + c = 0; + loop { + i = 0; + while i < end { + let mut j: i32 = 0; + let g: opus_val16 = + 1.0f32 / (1e-27f32 + *bandE.offset((i + c * (*m).nbEBands) as isize)); + j = M * *eBands.offset(i as isize) as i32; + while j < M * *eBands.offset((i + 1) as isize) as i32 { + *X.offset((j + c * N) as isize) = *freq.offset((j + c * N) as isize) * g; + j += 1; + } + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } +} +pub unsafe fn denormalise_bands( + m: *const OpusCustomMode, + X: *const celt_norm, + freq: *mut celt_sig, + bandLogE: *const opus_val16, + mut start: i32, + mut end: i32, + M: i32, + downsample: i32, + silence: i32, +) { + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut bound: i32 = 0; + let mut f: *mut celt_sig = 0 as *mut celt_sig; + let mut x: *const celt_norm = 0 as *const celt_norm; + let eBands: *const i16 = (*m).eBands; + N = M * (*m).shortMdctSize; + bound = M * *eBands.offset(end as isize) as i32; + if downsample != 1 { + bound = if bound < N / downsample { + bound + } else { + N / downsample + }; + } + if silence != 0 { + bound = 0; + end = 0; + start = end; + } + f = freq; + x = X.offset((M * *eBands.offset(start as isize) as i32) as isize); + i = 0; + while i < M * *eBands.offset(start as isize) as i32 { + let fresh0 = f; + f = f.offset(1); + *fresh0 = 0 as celt_sig; + i += 1; + } + i = start; + while i < end { + let mut j: i32 = 0; + let mut band_end: i32 = 0; + let mut g: opus_val16 = 0.; + let mut lg: opus_val16 = 0.; + j = M * *eBands.offset(i as isize) as i32; + band_end = M * *eBands.offset((i + 1) as isize) as i32; + lg = *bandLogE.offset(i as isize) + eMeans[i as usize]; + g = celt_exp2(if 32.0 < lg { 32.0f32 } else { lg }); + loop { + let fresh1 = x; + x = x.offset(1); + let fresh2 = f; + f = f.offset(1); + *fresh2 = *fresh1 * g; + j += 1; + if !(j < band_end) { + break; + } + } + i += 1; + } + assert!(start <= end); + memset( + &mut *freq.offset(bound as isize) as *mut celt_sig as *mut core::ffi::c_void, + 0, + ((N - bound) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); +} +pub unsafe fn anti_collapse( + m: *const OpusCustomMode, + X_: *mut celt_norm, + collapse_masks: *mut u8, + LM: i32, + C: i32, + size: i32, + start: i32, + end: i32, + logE: *const opus_val16, + prev1logE: *const opus_val16, + prev2logE: *const opus_val16, + pulses: *const i32, + mut seed: u32, + arch: i32, +) { + let mut c: i32 = 0; + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + i = start; + while i < end { + let mut N0: i32 = 0; + let mut thresh: opus_val16 = 0.; + let mut sqrt_1: opus_val16 = 0.; + let mut depth: i32 = 0; + N0 = *((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32; + depth = (celt_udiv( + (1 + *pulses.offset(i as isize)) as u32, + (*((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32) as u32, + ) >> LM) as i32; + thresh = 0.5f32 * celt_exp2(-0.125f32 * depth as f32); + sqrt_1 = celt_rsqrt((N0 << LM) as f32); + c = 0; + loop { + let mut X: *mut celt_norm = 0 as *mut celt_norm; + let mut prev1: opus_val16 = 0.; + let mut prev2: opus_val16 = 0.; + let mut Ediff: opus_val32 = 0.; + let mut r: opus_val16 = 0.; + let mut renormalize: i32 = 0; + prev1 = *prev1logE.offset((c * (*m).nbEBands + i) as isize); + prev2 = *prev2logE.offset((c * (*m).nbEBands + i) as isize); + if C == 1 { + prev1 = if prev1 > *prev1logE.offset(((*m).nbEBands + i) as isize) { + prev1 + } else { + *prev1logE.offset(((*m).nbEBands + i) as isize) + }; + prev2 = if prev2 > *prev2logE.offset(((*m).nbEBands + i) as isize) { + prev2 + } else { + *prev2logE.offset(((*m).nbEBands + i) as isize) + }; + } + Ediff = *logE.offset((c * (*m).nbEBands + i) as isize) + - (if prev1 < prev2 { prev1 } else { prev2 }); + Ediff = if 0 as f32 > Ediff { 0 as f32 } else { Ediff }; + r = 2.0f32 * celt_exp2(-Ediff); + if LM == 3 { + r *= 1.41421356f32; + } + r = if thresh < r { thresh } else { r }; + r = r * sqrt_1; + X = X_ + .offset((c * size) as isize) + .offset(((*((*m).eBands).offset(i as isize) as i32) << LM) as isize); + k = 0; + while k < (1) << LM { + if *collapse_masks.offset((i * C + c) as isize) as i32 & (1) << k == 0 { + j = 0; + while j < N0 { + seed = celt_lcg_rand(seed); + *X.offset(((j << LM) + k) as isize) = + if seed & 0x8000 != 0 { r } else { -r }; + j += 1; + } + renormalize = 1; + } + k += 1; + } + if renormalize != 0 { + renormalise_vector(X, N0 << LM, Q15ONE, arch); + } + c += 1; + if !(c < C) { + break; + } + } + i += 1; + } +} +unsafe fn compute_channel_weights(mut Ex: celt_ener, mut Ey: celt_ener, w: *mut opus_val16) { + let mut minE: celt_ener = 0.; + minE = if Ex < Ey { Ex } else { Ey }; + Ex = Ex + minE / 3 as f32; + Ey = Ey + minE / 3 as f32; + *w.offset(0 as isize) = Ex; + *w.offset(1 as isize) = Ey; +} +unsafe fn intensity_stereo( + m: *const OpusCustomMode, + X: *mut celt_norm, + Y: *const celt_norm, + bandE: *const celt_ener, + bandID: i32, + N: i32, +) { + let i: i32 = bandID; + let mut j: i32 = 0; + let mut a1: opus_val16 = 0.; + let mut a2: opus_val16 = 0.; + let mut left: opus_val16 = 0.; + let mut right: opus_val16 = 0.; + let mut norm: opus_val16 = 0.; + left = *bandE.offset(i as isize); + right = *bandE.offset((i + (*m).nbEBands) as isize); + norm = EPSILON + celt_sqrt(1e-15f32 + left * left + right * right); + a1 = left / norm; + a2 = right / norm; + j = 0; + while j < N { + let mut r: celt_norm = 0.; + let mut l: celt_norm = 0.; + l = *X.offset(j as isize); + r = *Y.offset(j as isize); + *X.offset(j as isize) = a1 * l + a2 * r; + j += 1; + } +} +unsafe fn stereo_split(X: *mut celt_norm, Y: *mut celt_norm, N: i32) { + let mut j: i32 = 0; + j = 0; + while j < N { + let mut r: opus_val32 = 0.; + let mut l: opus_val32 = 0.; + l = 0.70710678f32 * *X.offset(j as isize); + r = 0.70710678f32 * *Y.offset(j as isize); + *X.offset(j as isize) = l + r; + *Y.offset(j as isize) = r - l; + j += 1; + } +} +unsafe fn stereo_merge(X: *mut celt_norm, Y: *mut celt_norm, mid: opus_val16, N: i32, _arch: i32) { + let mut j: i32 = 0; + let mut xp: opus_val32 = 0 as opus_val32; + let mut side: opus_val32 = 0 as opus_val32; + let mut El: opus_val32 = 0.; + let mut Er: opus_val32 = 0.; + let mut mid2: opus_val16 = 0.; + let mut t: opus_val32 = 0.; + let mut lgain: opus_val32 = 0.; + let mut rgain: opus_val32 = 0.; + dual_inner_prod_c(Y, X, Y, N, &mut xp, &mut side); + xp = mid * xp; + mid2 = mid; + El = mid2 * mid2 + side - 2 as f32 * xp; + Er = mid2 * mid2 + side + 2 as f32 * xp; + if Er < 6e-4f32 || El < 6e-4f32 { + memcpy( + Y as *mut core::ffi::c_void, + X as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * Y.offset_from(X) as i64) as u64), + ); + return; + } + t = El; + lgain = celt_rsqrt_norm(t); + t = Er; + rgain = celt_rsqrt_norm(t); + j = 0; + while j < N { + let mut r: celt_norm = 0.; + let mut l: celt_norm = 0.; + l = mid * *X.offset(j as isize); + r = *Y.offset(j as isize); + *X.offset(j as isize) = lgain * (l - r); + *Y.offset(j as isize) = rgain * (l + r); + j += 1; + } +} +pub unsafe fn spreading_decision( + m: *const OpusCustomMode, + X: *const celt_norm, + average: *mut i32, + last_decision: i32, + hf_average: *mut i32, + tapset_decision: *mut i32, + update_hf: i32, + end: i32, + C: i32, + M: i32, + spread_weight: *const i32, +) -> i32 { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut N0: i32 = 0; + let mut sum: i32 = 0; + let mut nbBands: i32 = 0; + let eBands: *const i16 = (*m).eBands; + let mut decision: i32 = 0; + let mut hf_sum: i32 = 0; + assert!(end > 0); + N0 = M * (*m).shortMdctSize; + if M * (*eBands.offset(end as isize) as i32 - *eBands.offset((end - 1) as isize) as i32) <= 8 { + return SPREAD_NONE; + } + c = 0; + loop { + i = 0; + while i < end { + let mut j: i32 = 0; + let mut N: i32 = 0; + let mut tmp: i32 = 0; + let mut tcount: [i32; 3] = [0, 0, 0]; + let x: *const celt_norm = X + .offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset((c * N0) as isize); + N = M * (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32); + if !(N <= 8) { + j = 0; + while j < N { + let mut x2N: opus_val32 = 0.; + x2N = *x.offset(j as isize) * *x.offset(j as isize) * N as opus_val32; + if x2N < 0.25f32 { + tcount[0 as usize] += 1; + } + if x2N < 0.0625f32 { + tcount[1 as usize] += 1; + } + if x2N < 0.015625f32 { + tcount[2 as usize] += 1; + } + j += 1; + } + if i > (*m).nbEBands - 4 { + hf_sum = (hf_sum as u32).wrapping_add(celt_udiv( + (32 * (tcount[1 as usize] + tcount[0 as usize])) as u32, + N as u32, + )) as i32 as i32; + } + tmp = (2 * tcount[2 as usize] >= N) as i32 + + (2 * tcount[1 as usize] >= N) as i32 + + (2 * tcount[0 as usize] >= N) as i32; + sum += tmp * *spread_weight.offset(i as isize); + nbBands += *spread_weight.offset(i as isize); + } + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + if update_hf != 0 { + if hf_sum != 0 { + hf_sum = celt_udiv(hf_sum as u32, (C * (4 - (*m).nbEBands + end)) as u32) as i32; + } + *hf_average = *hf_average + hf_sum >> 1; + hf_sum = *hf_average; + if *tapset_decision == 2 { + hf_sum += 4; + } else if *tapset_decision == 0 { + hf_sum -= 4; + } + if hf_sum > 22 { + *tapset_decision = 2; + } else if hf_sum > 18 { + *tapset_decision = 1; + } else { + *tapset_decision = 0; + } + } + assert!(nbBands > 0); + assert!(sum >= 0); + sum = celt_udiv((sum << 8) as u32, nbBands as u32) as i32; + sum = sum + *average >> 1; + *average = sum; + sum = 3 * sum + ((3 - last_decision << 7) + 64) + 2 >> 2; + if sum < 80 { + decision = SPREAD_AGGRESSIVE; + } else if sum < 256 { + decision = SPREAD_NORMAL; + } else if sum < 384 { + decision = SPREAD_LIGHT; + } else { + decision = SPREAD_NONE; + } + return decision; +} +static mut ordery_table: [i32; 30] = [ + 1, 0, 3, 0, 2, 1, 7, 0, 4, 3, 6, 1, 5, 2, 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, +]; +unsafe fn deinterleave_hadamard(X: *mut celt_norm, N0: i32, stride: i32, hadamard: i32) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut N: i32 = 0; + N = N0 * stride; + let vla = N as usize; + let mut tmp: Vec = ::std::vec::from_elem(0., vla); + assert!(stride > 0); + if hadamard != 0 { + let ordery: *const i32 = ordery_table + .as_ptr() + .offset(stride as isize) + .offset(-(2 as isize)); + i = 0; + while i < stride { + j = 0; + while j < N0 { + *tmp.as_mut_ptr() + .offset((*ordery.offset(i as isize) * N0 + j) as isize) = + *X.offset((j * stride + i) as isize); + j += 1; + } + i += 1; + } + } else { + i = 0; + while i < stride { + j = 0; + while j < N0 { + *tmp.as_mut_ptr().offset((i * N0 + j) as isize) = + *X.offset((j * stride + i) as isize); + j += 1; + } + i += 1; + } + } + memcpy( + X as *mut core::ffi::c_void, + tmp.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * X.offset_from(tmp.as_mut_ptr()) as i64) as u64), + ); +} +unsafe fn interleave_hadamard(X: *mut celt_norm, N0: i32, stride: i32, hadamard: i32) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut N: i32 = 0; + N = N0 * stride; + let vla = N as usize; + let mut tmp: Vec = ::std::vec::from_elem(0., vla); + if hadamard != 0 { + let ordery: *const i32 = ordery_table + .as_ptr() + .offset(stride as isize) + .offset(-(2 as isize)); + i = 0; + while i < stride { + j = 0; + while j < N0 { + *tmp.as_mut_ptr().offset((j * stride + i) as isize) = + *X.offset((*ordery.offset(i as isize) * N0 + j) as isize); + j += 1; + } + i += 1; + } + } else { + i = 0; + while i < stride { + j = 0; + while j < N0 { + *tmp.as_mut_ptr().offset((j * stride + i) as isize) = + *X.offset((i * N0 + j) as isize); + j += 1; + } + i += 1; + } + } + memcpy( + X as *mut core::ffi::c_void, + tmp.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * X.offset_from(tmp.as_mut_ptr()) as i64) as u64), + ); +} +pub unsafe fn haar1(X: *mut celt_norm, mut N0: i32, stride: i32) { + let mut i: i32 = 0; + let mut j: i32 = 0; + N0 >>= 1; + i = 0; + while i < stride { + j = 0; + while j < N0 { + let mut tmp1: opus_val32 = 0.; + let mut tmp2: opus_val32 = 0.; + tmp1 = std::f32::consts::FRAC_1_SQRT_2 * *X.offset((stride * 2 * j + i) as isize); + tmp2 = std::f32::consts::FRAC_1_SQRT_2 * *X.offset((stride * (2 * j + 1) + i) as isize); + *X.offset((stride * 2 * j + i) as isize) = tmp1 + tmp2; + *X.offset((stride * (2 * j + 1) + i) as isize) = tmp1 - tmp2; + j += 1; + } + i += 1; + } +} +unsafe fn compute_qn(N: i32, b: i32, offset: i32, pulse_cap: i32, stereo: i32) -> i32 { + static mut exp2_table8: [i16; 8] = [16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048]; + let mut qn: i32 = 0; + let mut qb: i32 = 0; + let mut N2: i32 = 2 * N - 1; + if stereo != 0 && N == 2 { + N2 -= 1; + } + qb = celt_sudiv(b + N2 * offset, N2); + qb = if b - pulse_cap - ((4) << 3) < qb { + b - pulse_cap - ((4) << 3) + } else { + qb + }; + qb = if ((8) << 3) < qb { (8) << 3 } else { qb }; + if qb < (1) << BITRES >> 1 { + qn = 1; + } else { + qn = exp2_table8[(qb & 0x7) as usize] as i32 >> 14 - (qb >> BITRES); + qn = (qn + 1 >> 1) << 1; + } + assert!(qn <= 256); + return qn; +} +unsafe fn compute_theta( + ctx: *mut band_ctx, + sctx: *mut split_ctx, + X: *mut celt_norm, + Y: *mut celt_norm, + N: i32, + b: *mut i32, + B: i32, + B0: i32, + LM: i32, + stereo: i32, + fill: *mut i32, +) { + let mut qn: i32 = 0; + let mut itheta: i32 = 0; + let mut delta: i32 = 0; + let mut imid: i32 = 0; + let mut iside: i32 = 0; + let mut qalloc: i32 = 0; + let mut pulse_cap: i32 = 0; + let mut offset: i32 = 0; + let mut tell: i32 = 0; + let mut inv: i32 = 0; + let mut encode: i32 = 0; + let mut m: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut i: i32 = 0; + let mut intensity: i32 = 0; + let mut bandE: *const celt_ener = 0 as *const celt_ener; + encode = (*ctx).encode; + m = (*ctx).m; + i = (*ctx).i; + intensity = (*ctx).intensity; + let ec = &mut *(*ctx).ec; + bandE = (*ctx).bandE; + pulse_cap = *((*m).logN).offset(i as isize) as i32 + LM * ((1) << BITRES); + offset = (pulse_cap >> 1) + - (if stereo != 0 && N == 2 { + QTHETA_OFFSET_TWOPHASE + } else { + QTHETA_OFFSET + }); + qn = compute_qn(N, *b, offset, pulse_cap, stereo); + if stereo != 0 && i >= intensity { + qn = 1; + } + if encode != 0 { + itheta = stereo_itheta(X, Y, stereo, N, (*ctx).arch); + } + tell = ec_tell_frac(ec) as i32; + if qn != 1 { + if encode != 0 { + if stereo == 0 || (*ctx).theta_round == 0 { + itheta = itheta * qn + 8192 >> 14; + if stereo == 0 && (*ctx).avoid_split_noise != 0 && itheta > 0 && itheta < qn { + let unquantized: i32 = celt_udiv((itheta * 16384) as u32, qn as u32) as i32; + imid = bitexact_cos(unquantized as i16) as i32; + iside = bitexact_cos((16384 - unquantized) as i16) as i32; + delta = 16384 + + ((N - 1) << 7) as i16 as i32 + * bitexact_log2tan(iside, imid) as i16 as i32 + >> 15; + if delta > *b { + itheta = qn; + } else if delta < -*b { + itheta = 0; + } + } + } else { + let mut down: i32 = 0; + let bias: i32 = if itheta > 8192 { + 32767 / qn + } else { + -(32767) / qn + }; + down = if (qn - 1) + < (if 0 > itheta * qn + bias >> 14 { + 0 + } else { + itheta * qn + bias >> 14 + }) { + qn - 1 + } else if 0 > itheta * qn + bias >> 14 { + 0 + } else { + itheta * qn + bias >> 14 + }; + if (*ctx).theta_round < 0 { + itheta = down; + } else { + itheta = down + 1; + } + } + } + if stereo != 0 && N > 2 { + let p0: i32 = 3; + let mut x: i32 = itheta; + let x0: i32 = qn / 2; + let ft: i32 = p0 * (x0 + 1) + x0; + if encode != 0 { + ec_encode( + ec, + (if x <= x0 { + p0 * x + } else { + x - 1 - x0 + (x0 + 1) * p0 + }) as u32, + (if x <= x0 { + p0 * (x + 1) + } else { + x - x0 + (x0 + 1) * p0 + }) as u32, + ft as u32, + ); + } else { + let mut fs: i32 = 0; + fs = ec_decode(ec, ft as u32) as i32; + if fs < (x0 + 1) * p0 { + x = fs / p0; + } else { + x = x0 + 1 + (fs - (x0 + 1) * p0); + } + ec_dec_update( + ec, + (if x <= x0 { + p0 * x + } else { + x - 1 - x0 + (x0 + 1) * p0 + }) as u32, + (if x <= x0 { + p0 * (x + 1) + } else { + x - x0 + (x0 + 1) * p0 + }) as u32, + ft as u32, + ); + itheta = x; + } + } else if B0 > 1 || stereo != 0 { + if encode != 0 { + ec_enc_uint(ec, itheta as u32, (qn + 1) as u32); + } else { + itheta = ec_dec_uint(ec, (qn + 1) as u32) as i32; + } + } else { + let mut fs_0: i32 = 1; + let mut ft_0: i32 = 0; + ft_0 = ((qn >> 1) + 1) * ((qn >> 1) + 1); + if encode != 0 { + let mut fl: i32 = 0; + fs_0 = if itheta <= qn >> 1 { + itheta + 1 + } else { + qn + 1 - itheta + }; + fl = if itheta <= qn >> 1 { + itheta * (itheta + 1) >> 1 + } else { + ft_0 - ((qn + 1 - itheta) * (qn + 2 - itheta) >> 1) + }; + ec_encode(ec, fl as u32, (fl + fs_0) as u32, ft_0 as u32); + } else { + let mut fl_0: i32 = 0; + let mut fm: i32 = 0; + fm = ec_decode(ec, ft_0 as u32) as i32; + if fm < (qn >> 1) * ((qn >> 1) + 1) >> 1 { + itheta = ((isqrt32((8_u32).wrapping_mul(fm as u32).wrapping_add(1))) + .wrapping_sub(1) + >> 1) as i32; + fs_0 = itheta + 1; + fl_0 = itheta * (itheta + 1) >> 1; + } else { + itheta = (((2 * (qn + 1)) as u32).wrapping_sub(isqrt32( + (8_u32).wrapping_mul((ft_0 - fm - 1) as u32).wrapping_add(1), + )) >> 1) as i32; + fs_0 = qn + 1 - itheta; + fl_0 = ft_0 - ((qn + 1 - itheta) * (qn + 2 - itheta) >> 1); + } + ec_dec_update(ec, fl_0 as u32, (fl_0 + fs_0) as u32, ft_0 as u32); + } + } + assert!(itheta >= 0); + itheta = celt_udiv((itheta * 16384) as u32, qn as u32) as i32; + if encode != 0 && stereo != 0 { + if itheta == 0 { + intensity_stereo(m, X, Y, bandE, i, N); + } else { + stereo_split(X, Y, N); + } + } + } else if stereo != 0 { + if encode != 0 { + inv = (itheta > 8192 && (*ctx).disable_inv == 0) as i32; + if inv != 0 { + let mut j: i32 = 0; + j = 0; + while j < N { + *Y.offset(j as isize) = -*Y.offset(j as isize); + j += 1; + } + } + intensity_stereo(m, X, Y, bandE, i, N); + } + if *b > (2) << BITRES && (*ctx).remaining_bits > (2) << BITRES { + if encode != 0 { + ec_enc_bit_logp(ec, inv, 2); + } else { + inv = ec_dec_bit_logp(ec, 2); + } + } else { + inv = 0; + } + if (*ctx).disable_inv != 0 { + inv = 0; + } + itheta = 0; + } + qalloc = (ec_tell_frac(ec)).wrapping_sub(tell as u32) as i32; + *b -= qalloc; + if itheta == 0 { + imid = 32767; + iside = 0; + *fill &= ((1) << B) - 1; + delta = -(16384); + } else if itheta == 16384 { + imid = 0; + iside = 32767; + *fill &= (((1) << B) - 1) << B; + delta = 16384; + } else { + imid = bitexact_cos(itheta as i16) as i32; + iside = bitexact_cos((16384 - itheta) as i16) as i32; + delta = 16384 + ((N - 1) << 7) as i16 as i32 * bitexact_log2tan(iside, imid) as i16 as i32 + >> 15; + } + (*sctx).inv = inv; + (*sctx).imid = imid; + (*sctx).iside = iside; + (*sctx).delta = delta; + (*sctx).itheta = itheta; + (*sctx).qalloc = qalloc; +} +unsafe fn quant_band_n1( + ctx: *mut band_ctx, + X: *mut celt_norm, + Y: *mut celt_norm, + mut _b: i32, + lowband_out: *mut celt_norm, +) -> u32 { + let mut c: i32 = 0; + let mut stereo: i32 = 0; + let mut x: *mut celt_norm = X; + let mut encode: i32 = 0; + encode = (*ctx).encode; + let ec = &mut *(*ctx).ec; + stereo = (Y != NULL as *mut celt_norm) as i32; + c = 0; + loop { + let mut sign: i32 = 0; + if (*ctx).remaining_bits >= (1) << BITRES { + if encode != 0 { + sign = (*x.offset(0 as isize) < 0 as f32) as i32; + ec_enc_bits(ec, sign as u32, 1); + } else { + sign = ec_dec_bits(ec, 1) as i32; + } + (*ctx).remaining_bits -= (1) << BITRES; + _b -= (1) << BITRES; + } + if (*ctx).resynth != 0 { + *x.offset(0 as isize) = if sign != 0 { + -NORM_SCALING + } else { + NORM_SCALING + }; + } + x = Y; + c += 1; + if !(c < 1 + stereo) { + break; + } + } + if !lowband_out.is_null() { + *lowband_out.offset(0 as isize) = *X.offset(0 as isize); + } + return 1; +} +unsafe fn quant_partition( + ctx: *mut band_ctx, + X: *mut celt_norm, + mut N: i32, + mut b: i32, + mut B: i32, + lowband: *mut celt_norm, + mut LM: i32, + gain: opus_val16, + mut fill: i32, +) -> u32 { + let mut cache: *const u8 = 0 as *const u8; + let mut q: i32 = 0; + let mut curr_bits: i32 = 0; + let mut imid: i32 = 0; + let mut iside: i32 = 0; + let B0: i32 = B; + let mut mid: opus_val16 = 0 as opus_val16; + let mut side: opus_val16 = 0 as opus_val16; + let mut cm: u32 = 0; + let mut Y: *mut celt_norm = NULL as *mut celt_norm; + let mut encode: i32 = 0; + let mut m: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut i: i32 = 0; + let mut spread: i32 = 0; + encode = (*ctx).encode; + m = (*ctx).m; + i = (*ctx).i; + spread = (*ctx).spread; + let ec = &mut *(*ctx).ec; + cache = ((*m).cache.bits).offset( + *((*m).cache.index).offset(((LM + 1) * (*m).nbEBands + i) as isize) as i32 as isize, + ); + if LM != -1 && b > *cache.offset(*cache.offset(0 as isize) as isize) as i32 + 12 && N > 2 { + let mut mbits: i32 = 0; + let mut sbits: i32 = 0; + let mut delta: i32 = 0; + let mut itheta: i32 = 0; + let mut qalloc: i32 = 0; + let mut sctx: split_ctx = split_ctx { + inv: 0, + imid: 0, + iside: 0, + delta: 0, + itheta: 0, + qalloc: 0, + }; + let mut next_lowband2: *mut celt_norm = NULL as *mut celt_norm; + let mut rebalance: i32 = 0; + N >>= 1; + Y = X.offset(N as isize); + LM -= 1; + if B == 1 { + fill = fill & 1 | fill << 1; + } + B = B + 1 >> 1; + compute_theta(ctx, &mut sctx, X, Y, N, &mut b, B, B0, LM, 0, &mut fill); + imid = sctx.imid; + iside = sctx.iside; + delta = sctx.delta; + itheta = sctx.itheta; + qalloc = sctx.qalloc; + mid = 1.0f32 / 32768 as f32 * imid as f32; + side = 1.0f32 / 32768 as f32 * iside as f32; + if B0 > 1 && itheta & 0x3fff != 0 { + if itheta > 8192 { + delta -= delta >> 4 - LM; + } else { + delta = if (0) < delta + (N << 3 >> 5 - LM) { + 0 + } else { + delta + (N << 3 >> 5 - LM) + }; + } + } + mbits = if 0 + > (if b < (b - delta) / 2 { + b + } else { + (b - delta) / 2 + }) { + 0 + } else if b < (b - delta) / 2 { + b + } else { + (b - delta) / 2 + }; + sbits = b - mbits; + (*ctx).remaining_bits -= qalloc; + if !lowband.is_null() { + next_lowband2 = lowband.offset(N as isize); + } + rebalance = (*ctx).remaining_bits; + if mbits >= sbits { + cm = quant_partition(ctx, X, N, mbits, B, lowband, LM, gain * mid, fill); + rebalance = mbits - (rebalance - (*ctx).remaining_bits); + if rebalance > (3) << BITRES && itheta != 0 { + sbits += rebalance - ((3) << BITRES); + } + cm |= quant_partition( + ctx, + Y, + N, + sbits, + B, + next_lowband2, + LM, + gain * side, + fill >> B, + ) << (B0 >> 1); + } else { + cm = quant_partition( + ctx, + Y, + N, + sbits, + B, + next_lowband2, + LM, + gain * side, + fill >> B, + ) << (B0 >> 1); + rebalance = sbits - (rebalance - (*ctx).remaining_bits); + if rebalance > (3) << BITRES && itheta != 16384 { + mbits += rebalance - ((3) << BITRES); + } + cm |= quant_partition(ctx, X, N, mbits, B, lowband, LM, gain * mid, fill); + } + } else { + q = bits2pulses(m, i, LM, b); + curr_bits = pulses2bits(m, i, LM, q); + (*ctx).remaining_bits -= curr_bits; + while (*ctx).remaining_bits < 0 && q > 0 { + (*ctx).remaining_bits += curr_bits; + q -= 1; + curr_bits = pulses2bits(m, i, LM, q); + (*ctx).remaining_bits -= curr_bits; + } + if q != 0 { + let K: i32 = get_pulses(q); + if encode != 0 { + cm = alg_quant( + X, + N, + K, + spread, + B, + &mut *ec, + gain, + (*ctx).resynth, + (*ctx).arch, + ); + } else { + cm = alg_unquant(X, N, K, spread, B, ec, gain); + } + } else { + let mut j: i32 = 0; + if (*ctx).resynth != 0 { + let mut cm_mask: u32 = 0; + cm_mask = (((1 as u64) << B) as u32).wrapping_sub(1); + fill = (fill as u32 & cm_mask) as i32; + if fill == 0 { + memset( + X as *mut core::ffi::c_void, + 0, + (N as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } else { + if lowband.is_null() { + j = 0; + while j < N { + (*ctx).seed = celt_lcg_rand((*ctx).seed); + *X.offset(j as isize) = ((*ctx).seed as i32 >> 20) as celt_norm; + j += 1; + } + cm = cm_mask; + } else { + j = 0; + while j < N { + let mut tmp: opus_val16 = 0.; + (*ctx).seed = celt_lcg_rand((*ctx).seed); + tmp = 1.0f32 / 256 as f32; + tmp = if (*ctx).seed & 0x8000 != 0 { tmp } else { -tmp }; + *X.offset(j as isize) = *lowband.offset(j as isize) + tmp; + j += 1; + } + cm = fill as u32; + } + renormalise_vector(X, N, gain, (*ctx).arch); + } + } + } + } + return cm; +} +unsafe fn quant_band( + ctx: *mut band_ctx, + X: *mut celt_norm, + N: i32, + b: i32, + mut B: i32, + mut lowband: *mut celt_norm, + LM: i32, + lowband_out: *mut celt_norm, + gain: opus_val16, + lowband_scratch: *mut celt_norm, + mut fill: i32, +) -> u32 { + let N0: i32 = N; + let mut N_B: i32 = N; + let mut N_B0: i32 = 0; + let mut B0: i32 = B; + let mut time_divide: i32 = 0; + let mut recombine: i32 = 0; + let mut longBlocks: i32 = 0; + let mut cm: u32 = 0; + let mut k: i32 = 0; + let mut encode: i32 = 0; + let mut tf_change: i32 = 0; + encode = (*ctx).encode; + tf_change = (*ctx).tf_change; + longBlocks = (B0 == 1) as i32; + N_B = celt_udiv(N_B as u32, B as u32) as i32; + if N == 1 { + return quant_band_n1(ctx, X, NULL as *mut celt_norm, b, lowband_out); + } + if tf_change > 0 { + recombine = tf_change; + } + if !lowband_scratch.is_null() + && !lowband.is_null() + && (recombine != 0 || N_B & 1 == 0 && tf_change < 0 || B0 > 1) + { + memcpy( + lowband_scratch as *mut core::ffi::c_void, + lowband as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * lowband_scratch.offset_from(lowband) as i64) as u64), + ); + lowband = lowband_scratch; + } + k = 0; + while k < recombine { + static mut bit_interleave_table: [u8; 16] = + [0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3]; + if encode != 0 { + haar1(X, N >> k, (1) << k); + } + if !lowband.is_null() { + haar1(lowband, N >> k, (1) << k); + } + fill = bit_interleave_table[(fill & 0xf) as usize] as i32 + | (bit_interleave_table[(fill >> 4) as usize] as i32) << 2; + k += 1; + } + B >>= recombine; + N_B <<= recombine; + while N_B & 1 == 0 && tf_change < 0 { + if encode != 0 { + haar1(X, N_B, B); + } + if !lowband.is_null() { + haar1(lowband, N_B, B); + } + fill |= fill << B; + B <<= 1; + N_B >>= 1; + time_divide += 1; + tf_change += 1; + } + B0 = B; + N_B0 = N_B; + if B0 > 1 { + if encode != 0 { + deinterleave_hadamard(X, N_B >> recombine, B0 << recombine, longBlocks); + } + if !lowband.is_null() { + deinterleave_hadamard(lowband, N_B >> recombine, B0 << recombine, longBlocks); + } + } + cm = quant_partition(ctx, X, N, b, B, lowband, LM, gain, fill); + if (*ctx).resynth != 0 { + if B0 > 1 { + interleave_hadamard(X, N_B >> recombine, B0 << recombine, longBlocks); + } + N_B = N_B0; + B = B0; + k = 0; + while k < time_divide { + B >>= 1; + N_B <<= 1; + cm |= cm >> B; + haar1(X, N_B, B); + k += 1; + } + k = 0; + while k < recombine { + static mut bit_deinterleave_table: [u8; 16] = [ + 0, 0x3, 0xc, 0xf, 0x30, 0x33, 0x3c, 0x3f, 0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, + 0xff, + ]; + cm = bit_deinterleave_table[cm as usize] as u32; + haar1(X, N0 >> k, (1) << k); + k += 1; + } + B <<= recombine; + if !lowband_out.is_null() { + let mut j: i32 = 0; + let mut n: opus_val16 = 0.; + n = celt_sqrt(N0 as f32); + j = 0; + while j < N0 { + *lowband_out.offset(j as isize) = n * *X.offset(j as isize); + j += 1; + } + } + cm &= (((1) << B) - 1) as u32; + } + return cm; +} +unsafe fn quant_band_stereo( + ctx: *mut band_ctx, + X: *mut celt_norm, + Y: *mut celt_norm, + N: i32, + mut b: i32, + B: i32, + lowband: *mut celt_norm, + LM: i32, + lowband_out: *mut celt_norm, + lowband_scratch: *mut celt_norm, + mut fill: i32, +) -> u32 { + let mut imid: i32 = 0; + let mut iside: i32 = 0; + let mut inv: i32 = 0; + let mut mid: opus_val16 = 0 as opus_val16; + let mut side: opus_val16 = 0 as opus_val16; + let mut cm: u32 = 0; + let mut mbits: i32 = 0; + let mut sbits: i32 = 0; + let mut delta: i32 = 0; + let mut itheta: i32 = 0; + let mut qalloc: i32 = 0; + let mut sctx: split_ctx = split_ctx { + inv: 0, + imid: 0, + iside: 0, + delta: 0, + itheta: 0, + qalloc: 0, + }; + let mut orig_fill: i32 = 0; + let mut encode: i32 = 0; + encode = (*ctx).encode; + let ec = &mut *(*ctx).ec; + if N == 1 { + return quant_band_n1(ctx, X, Y, b, lowband_out); + } + orig_fill = fill; + compute_theta(ctx, &mut sctx, X, Y, N, &mut b, B, B, LM, 1, &mut fill); + inv = sctx.inv; + imid = sctx.imid; + iside = sctx.iside; + delta = sctx.delta; + itheta = sctx.itheta; + qalloc = sctx.qalloc; + mid = 1.0f32 / 32768 as f32 * imid as f32; + side = 1.0f32 / 32768 as f32 * iside as f32; + if N == 2 { + let mut c: i32 = 0; + let mut sign: i32 = 0; + let mut x2: *mut celt_norm = 0 as *mut celt_norm; + let mut y2: *mut celt_norm = 0 as *mut celt_norm; + mbits = b; + sbits = 0; + if itheta != 0 && itheta != 16384 { + sbits = (1) << BITRES; + } + mbits -= sbits; + c = (itheta > 8192) as i32; + (*ctx).remaining_bits -= qalloc + sbits; + x2 = if c != 0 { Y } else { X }; + y2 = if c != 0 { X } else { Y }; + if sbits != 0 { + if encode != 0 { + sign = (*x2.offset(0 as isize) * *y2.offset(1 as isize) + - *x2.offset(1 as isize) * *y2.offset(0 as isize) + < 0 as f32) as i32; + ec_enc_bits(ec, sign as u32, 1); + } else { + sign = ec_dec_bits(ec, 1) as i32; + } + } + sign = 1 - 2 * sign; + cm = quant_band( + ctx, + x2, + N, + mbits, + B, + lowband, + LM, + lowband_out, + Q15ONE, + lowband_scratch, + orig_fill, + ); + *y2.offset(0 as isize) = -sign as f32 * *x2.offset(1 as isize); + *y2.offset(1 as isize) = sign as f32 * *x2.offset(0 as isize); + if (*ctx).resynth != 0 { + let mut tmp: celt_norm = 0.; + *X.offset(0 as isize) = mid * *X.offset(0 as isize); + *X.offset(1 as isize) = mid * *X.offset(1 as isize); + *Y.offset(0 as isize) = side * *Y.offset(0 as isize); + *Y.offset(1 as isize) = side * *Y.offset(1 as isize); + tmp = *X.offset(0 as isize); + *X.offset(0 as isize) = tmp - *Y.offset(0 as isize); + *Y.offset(0 as isize) = tmp + *Y.offset(0 as isize); + tmp = *X.offset(1 as isize); + *X.offset(1 as isize) = tmp - *Y.offset(1 as isize); + *Y.offset(1 as isize) = tmp + *Y.offset(1 as isize); + } + } else { + let mut rebalance: i32 = 0; + mbits = if 0 + > (if b < (b - delta) / 2 { + b + } else { + (b - delta) / 2 + }) { + 0 + } else if b < (b - delta) / 2 { + b + } else { + (b - delta) / 2 + }; + sbits = b - mbits; + (*ctx).remaining_bits -= qalloc; + rebalance = (*ctx).remaining_bits; + if mbits >= sbits { + cm = quant_band( + ctx, + X, + N, + mbits, + B, + lowband, + LM, + lowband_out, + Q15ONE, + lowband_scratch, + fill, + ); + rebalance = mbits - (rebalance - (*ctx).remaining_bits); + if rebalance > (3) << BITRES && itheta != 0 { + sbits += rebalance - ((3) << BITRES); + } + cm |= quant_band( + ctx, + Y, + N, + sbits, + B, + NULL as *mut celt_norm, + LM, + NULL as *mut celt_norm, + side, + NULL as *mut celt_norm, + fill >> B, + ); + } else { + cm = quant_band( + ctx, + Y, + N, + sbits, + B, + NULL as *mut celt_norm, + LM, + NULL as *mut celt_norm, + side, + NULL as *mut celt_norm, + fill >> B, + ); + rebalance = sbits - (rebalance - (*ctx).remaining_bits); + if rebalance > (3) << BITRES && itheta != 16384 { + mbits += rebalance - ((3) << BITRES); + } + cm |= quant_band( + ctx, + X, + N, + mbits, + B, + lowband, + LM, + lowband_out, + Q15ONE, + lowband_scratch, + fill, + ); + } + } + if (*ctx).resynth != 0 { + if N != 2 { + stereo_merge(X, Y, mid, N, (*ctx).arch); + } + if inv != 0 { + let mut j: i32 = 0; + j = 0; + while j < N { + *Y.offset(j as isize) = -*Y.offset(j as isize); + j += 1; + } + } + } + return cm; +} +unsafe fn special_hybrid_folding( + m: *const OpusCustomMode, + norm: *mut celt_norm, + norm2: *mut celt_norm, + start: i32, + M: i32, + dual_stereo: i32, +) { + let mut n1: i32 = 0; + let mut n2: i32 = 0; + let eBands: *const i16 = (*m).eBands; + n1 = M * (*eBands.offset((start + 1) as isize) as i32 - *eBands.offset(start as isize) as i32); + n2 = M + * (*eBands.offset((start + 2) as isize) as i32 + - *eBands.offset((start + 1) as isize) as i32); + memcpy( + &mut *norm.offset(n1 as isize) as *mut celt_norm as *mut core::ffi::c_void, + &mut *norm.offset((2 * n1 - n2) as isize) as *mut celt_norm as *const core::ffi::c_void, + ((n2 - n1) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut *norm.offset(n1 as isize) as *mut celt_norm) + .offset_from(&mut *norm.offset((2 * n1 - n2) as isize)) + as i64) as u64, + ), + ); + if dual_stereo != 0 { + memcpy( + &mut *norm2.offset(n1 as isize) as *mut celt_norm as *mut core::ffi::c_void, + &mut *norm2.offset((2 * n1 - n2) as isize) as *mut celt_norm + as *const core::ffi::c_void, + ((n2 - n1) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut *norm2.offset(n1 as isize) as *mut celt_norm) + .offset_from(&mut *norm2.offset((2 * n1 - n2) as isize)) + as i64) as u64, + ), + ); + } +} +pub unsafe fn quant_all_bands( + encode: i32, + m: *const OpusCustomMode, + start: i32, + end: i32, + X_: *mut celt_norm, + Y_: *mut celt_norm, + collapse_masks: *mut u8, + bandE: *const celt_ener, + pulses: *mut i32, + shortBlocks: i32, + spread: i32, + mut dual_stereo: i32, + intensity: i32, + tf_res: *mut i32, + total_bits: i32, + mut balance: i32, + ec: &mut ec_ctx, + LM: i32, + codedBands: i32, + seed: *mut u32, + complexity: i32, + arch: i32, + disable_inv: i32, +) { + let mut i: i32 = 0; + let mut remaining_bits: i32 = 0; + let eBands: *const i16 = (*m).eBands; + let mut norm: *mut celt_norm = 0 as *mut celt_norm; + let mut norm2: *mut celt_norm = 0 as *mut celt_norm; + let mut resynth_alloc: i32 = 0; + let mut lowband_scratch: *mut celt_norm = 0 as *mut celt_norm; + let mut B: i32 = 0; + let mut M: i32 = 0; + let mut lowband_offset: i32 = 0; + let mut update_lowband: i32 = 1; + let C: i32 = if !Y_.is_null() { 2 } else { 1 }; + let mut norm_offset: i32 = 0; + let theta_rdo: i32 = + (encode != 0 && !Y_.is_null() && dual_stereo == 0 && complexity >= 8) as i32; + let resynth: i32 = (encode == 0 || theta_rdo != 0) as i32; + let mut ctx: band_ctx = band_ctx { + encode: 0, + resynth: 0, + m: 0 as *const OpusCustomMode, + i: 0, + intensity: 0, + spread: 0, + tf_change: 0, + ec: 0 as *mut ec_ctx, + remaining_bits: 0, + bandE: 0 as *const celt_ener, + seed: 0, + arch: 0, + theta_round: 0, + disable_inv: 0, + avoid_split_noise: 0, + }; + M = (1) << LM; + B = if shortBlocks != 0 { M } else { 1 }; + norm_offset = M * *eBands.offset(start as isize) as i32; + let vla = + (C * (M * *eBands.offset(((*m).nbEBands - 1) as isize) as i32 - norm_offset)) as usize; + let mut _norm: Vec = ::std::vec::from_elem(0., vla); + norm = _norm.as_mut_ptr(); + norm2 = norm + .offset((M * *eBands.offset(((*m).nbEBands - 1) as isize) as i32) as isize) + .offset(-(norm_offset as isize)); + if encode != 0 && resynth != 0 { + resynth_alloc = M + * (*eBands.offset((*m).nbEBands as isize) as i32 + - *eBands.offset(((*m).nbEBands - 1) as isize) as i32); + } else { + resynth_alloc = ALLOC_NONE; + } + let vla_0 = resynth_alloc as usize; + let mut _lowband_scratch: Vec = ::std::vec::from_elem(0., vla_0); + if encode != 0 && resynth != 0 { + lowband_scratch = _lowband_scratch.as_mut_ptr(); + } else { + lowband_scratch = + X_.offset((M * *eBands.offset(((*m).nbEBands - 1) as isize) as i32) as isize); + } + let vla_1 = resynth_alloc as usize; + let mut X_save: Vec = ::std::vec::from_elem(0., vla_1); + let vla_2 = resynth_alloc as usize; + let mut Y_save: Vec = ::std::vec::from_elem(0., vla_2); + let vla_3 = resynth_alloc as usize; + let mut X_save2: Vec = ::std::vec::from_elem(0., vla_3); + let vla_4 = resynth_alloc as usize; + let mut Y_save2: Vec = ::std::vec::from_elem(0., vla_4); + let vla_5 = resynth_alloc as usize; + let mut norm_save2: Vec = ::std::vec::from_elem(0., vla_5); + lowband_offset = 0; + ctx.bandE = bandE; + ctx.ec = ec; + ctx.encode = encode; + ctx.intensity = intensity; + ctx.m = m; + ctx.seed = *seed; + ctx.spread = spread; + ctx.arch = arch; + ctx.disable_inv = disable_inv; + ctx.resynth = resynth; + ctx.theta_round = 0; + ctx.avoid_split_noise = (B > 1) as i32; + i = start; + while i < end { + let mut tell: i32 = 0; + let mut b: i32 = 0; + let mut N: i32 = 0; + let mut curr_balance: i32 = 0; + let mut effective_lowband: i32 = -1; + let mut X: *mut celt_norm = 0 as *mut celt_norm; + let mut Y: *mut celt_norm = 0 as *mut celt_norm; + let mut tf_change: i32 = 0; + let mut x_cm: u32 = 0; + let mut y_cm: u32 = 0; + let mut last: i32 = 0; + ctx.i = i; + last = (i == end - 1) as i32; + X = X_.offset((M * *eBands.offset(i as isize) as i32) as isize); + if !Y_.is_null() { + Y = Y_.offset((M * *eBands.offset(i as isize) as i32) as isize); + } else { + Y = NULL as *mut celt_norm; + } + N = M * *eBands.offset((i + 1) as isize) as i32 - M * *eBands.offset(i as isize) as i32; + assert!(N > 0); + tell = ec_tell_frac(&mut *ec) as i32; + if i != start { + balance -= tell; + } + remaining_bits = total_bits - tell - 1; + ctx.remaining_bits = remaining_bits; + if i <= codedBands - 1 { + curr_balance = celt_sudiv( + balance, + if (3) < codedBands - i { + 3 + } else { + codedBands - i + }, + ); + b = + if 0 > (if (16383) + < (if (remaining_bits + 1) < *pulses.offset(i as isize) + curr_balance { + remaining_bits + 1 + } else { + *pulses.offset(i as isize) + curr_balance + }) { + 16383 + } else { + if (remaining_bits + 1) < *pulses.offset(i as isize) + curr_balance { + remaining_bits + 1 + } else { + *pulses.offset(i as isize) + curr_balance + } + }) { + 0 + } else if (16383) + < (if (remaining_bits + 1) < *pulses.offset(i as isize) + curr_balance { + remaining_bits + 1 + } else { + *pulses.offset(i as isize) + curr_balance + }) + { + 16383 + } else if (remaining_bits + 1) < *pulses.offset(i as isize) + curr_balance { + remaining_bits + 1 + } else { + *pulses.offset(i as isize) + curr_balance + }; + } else { + b = 0; + } + if resynth != 0 + && (M * *eBands.offset(i as isize) as i32 - N + >= M * *eBands.offset(start as isize) as i32 + || i == start + 1) + && (update_lowband != 0 || lowband_offset == 0) + { + lowband_offset = i; + } + if i == start + 1 { + special_hybrid_folding(m, norm, norm2, start, M, dual_stereo); + } + tf_change = *tf_res.offset(i as isize); + ctx.tf_change = tf_change; + if i >= (*m).effEBands { + X = norm; + if !Y_.is_null() { + Y = norm; + } + lowband_scratch = NULL as *mut celt_norm; + } + if last != 0 && theta_rdo == 0 { + lowband_scratch = NULL as *mut celt_norm; + } + if lowband_offset != 0 && (spread != SPREAD_AGGRESSIVE || B > 1 || tf_change < 0) { + let mut fold_start: i32 = 0; + let mut fold_end: i32 = 0; + let mut fold_i: i32 = 0; + effective_lowband = + if 0 > M * *eBands.offset(lowband_offset as isize) as i32 - norm_offset - N { + 0 + } else { + M * *eBands.offset(lowband_offset as isize) as i32 - norm_offset - N + }; + fold_start = lowband_offset; + loop { + fold_start -= 1; + if !(M * *eBands.offset(fold_start as isize) as i32 + > effective_lowband + norm_offset) + { + break; + } + } + fold_end = lowband_offset - 1; + loop { + fold_end += 1; + if !(fold_end < i + && (M * *eBands.offset(fold_end as isize) as i32) + < effective_lowband + norm_offset + N) + { + break; + } + } + y_cm = 0; + x_cm = y_cm; + fold_i = fold_start; + loop { + x_cm |= *collapse_masks.offset((fold_i * C + 0) as isize) as u32; + y_cm |= *collapse_masks.offset((fold_i * C + C - 1) as isize) as u32; + fold_i += 1; + if !(fold_i < fold_end) { + break; + } + } + } else { + y_cm = (((1) << B) - 1) as u32; + x_cm = y_cm; + } + if dual_stereo != 0 && i == intensity { + let mut j: i32 = 0; + dual_stereo = 0; + if resynth != 0 { + j = 0; + while j < M * *eBands.offset(i as isize) as i32 - norm_offset { + *norm.offset(j as isize) = + 0.5f32 * (*norm.offset(j as isize) + *norm2.offset(j as isize)); + j += 1; + } + } + } + if dual_stereo != 0 { + x_cm = quant_band( + &mut ctx, + X, + N, + b / 2, + B, + if effective_lowband != -1 { + norm.offset(effective_lowband as isize) + } else { + NULL as *mut celt_norm + }, + LM, + if last != 0 { + NULL as *mut celt_norm + } else { + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + }, + Q15ONE, + lowband_scratch, + x_cm as i32, + ); + y_cm = quant_band( + &mut ctx, + Y, + N, + b / 2, + B, + if effective_lowband != -1 { + norm2.offset(effective_lowband as isize) + } else { + NULL as *mut celt_norm + }, + LM, + if last != 0 { + NULL as *mut celt_norm + } else { + norm2 + .offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + }, + Q15ONE, + lowband_scratch, + y_cm as i32, + ); + } else { + if !Y.is_null() { + if theta_rdo != 0 && i < intensity { + let mut ec_save = ec_ctx_saved::default(); + let mut ec_save2 = ec_ctx_saved::default(); + let mut ctx_save: band_ctx = band_ctx { + encode: 0, + resynth: 0, + m: 0 as *const OpusCustomMode, + i: 0, + intensity: 0, + spread: 0, + tf_change: 0, + ec: 0 as *mut ec_ctx, + remaining_bits: 0, + bandE: 0 as *const celt_ener, + seed: 0, + arch: 0, + theta_round: 0, + disable_inv: 0, + avoid_split_noise: 0, + }; + let mut ctx_save2: band_ctx = band_ctx { + encode: 0, + resynth: 0, + m: 0 as *const OpusCustomMode, + i: 0, + intensity: 0, + spread: 0, + tf_change: 0, + ec: 0 as *mut ec_ctx, + remaining_bits: 0, + bandE: 0 as *const celt_ener, + seed: 0, + arch: 0, + theta_round: 0, + disable_inv: 0, + avoid_split_noise: 0, + }; + let mut dist0: opus_val32 = 0.; + let mut dist1: opus_val32 = 0.; + let mut cm: u32 = 0; + let mut cm2: u32 = 0; + let mut nstart_bytes: i32 = 0; + let mut nend_bytes: i32 = 0; + let mut save_bytes: i32 = 0; + let mut bytes_buf: *const u8 = 0 as *const u8; + let mut bytes_save: [u8; 1275] = [0; 1275]; + let mut w: [opus_val16; 2] = [0.; 2]; + compute_channel_weights( + *bandE.offset(i as isize), + *bandE.offset((i + (*m).nbEBands) as isize), + w.as_mut_ptr(), + ); + cm = x_cm | y_cm; + ec_save = (*ec).save(); + ctx_save = ctx; + memcpy( + X_save.as_mut_ptr() as *mut core::ffi::c_void, + X as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * X_save.as_mut_ptr().offset_from(X) as i64) as u64), + ); + memcpy( + Y_save.as_mut_ptr() as *mut core::ffi::c_void, + Y as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * Y_save.as_mut_ptr().offset_from(Y) as i64) as u64), + ); + ctx.theta_round = -1; + x_cm = quant_band_stereo( + &mut ctx, + X, + Y, + N, + b, + B, + if effective_lowband != -1 { + norm.offset(effective_lowband as isize) + } else { + NULL as *mut celt_norm + }, + LM, + if last != 0 { + NULL as *mut celt_norm + } else { + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + }, + lowband_scratch, + cm as i32, + ); + dist0 = w[0 as usize] * celt_inner_prod_c(X_save.as_mut_ptr(), X, N) + + w[1 as usize] * celt_inner_prod_c(Y_save.as_mut_ptr(), Y, N); + cm2 = x_cm; + ec_save2 = (*ec).save(); + ctx_save2 = ctx; + memcpy( + X_save2.as_mut_ptr() as *mut core::ffi::c_void, + X as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * X_save2.as_mut_ptr().offset_from(X) as i64) as u64), + ); + memcpy( + Y_save2.as_mut_ptr() as *mut core::ffi::c_void, + Y as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * Y_save2.as_mut_ptr().offset_from(Y) as i64) as u64), + ); + if last == 0 { + memcpy( + norm_save2.as_mut_ptr() as *mut core::ffi::c_void, + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * norm_save2.as_mut_ptr().offset_from( + norm.offset( + (M * *eBands.offset(i as isize) as i32) as isize, + ) + .offset(-(norm_offset as isize)), + ) as i64) as u64, + ), + ); + } + nstart_bytes = ec_save.offs as i32; + nend_bytes = (*ec).storage as i32; + bytes_buf = ec.buf.as_ptr().offset(nstart_bytes as isize); + save_bytes = nend_bytes - nstart_bytes; + memcpy( + bytes_save.as_mut_ptr() as *mut core::ffi::c_void, + bytes_buf as *const core::ffi::c_void, + (save_bytes as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * bytes_save.as_mut_ptr().offset_from(bytes_buf) as i64) as u64, + ), + ); + (*ec).restore(ec_save); + ctx = ctx_save; + memcpy( + X as *mut core::ffi::c_void, + X_save.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * X.offset_from(X_save.as_mut_ptr()) as i64) as u64), + ); + memcpy( + Y as *mut core::ffi::c_void, + Y_save.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * Y.offset_from(Y_save.as_mut_ptr()) as i64) as u64), + ); + if i == start + 1 { + special_hybrid_folding(m, norm, norm2, start, M, dual_stereo); + } + ctx.theta_round = 1; + x_cm = quant_band_stereo( + &mut ctx, + X, + Y, + N, + b, + B, + if effective_lowband != -1 { + norm.offset(effective_lowband as isize) + } else { + NULL as *mut celt_norm + }, + LM, + if last != 0 { + NULL as *mut celt_norm + } else { + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + }, + lowband_scratch, + cm as i32, + ); + dist1 = w[0 as usize] * celt_inner_prod_c(X_save.as_mut_ptr(), X, N) + + w[1 as usize] * celt_inner_prod_c(Y_save.as_mut_ptr(), Y, N); + if dist0 >= dist1 { + x_cm = cm2; + (*ec).restore(ec_save2); + ctx = ctx_save2; + memcpy( + X as *mut core::ffi::c_void, + X_save2.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * X.offset_from(X_save2.as_mut_ptr()) as i64) as u64, + ), + ); + memcpy( + Y as *mut core::ffi::c_void, + Y_save2.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * Y.offset_from(Y_save2.as_mut_ptr()) as i64) as u64, + ), + ); + if last == 0 { + memcpy( + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + as *mut core::ffi::c_void, + norm_save2.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * norm + .offset( + (M * *eBands.offset(i as isize) as i32) as isize, + ) + .offset(-(norm_offset as isize)) + .offset_from(norm_save2.as_mut_ptr()) + as i64) as u64, + ), + ); + } + memcpy( + bytes_buf as *mut core::ffi::c_void, + bytes_save.as_mut_ptr() as *const core::ffi::c_void, + (save_bytes as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * bytes_buf.offset_from(bytes_save.as_mut_ptr()) as i64) + as u64, + ), + ); + } + } else { + ctx.theta_round = 0; + x_cm = quant_band_stereo( + &mut ctx, + X, + Y, + N, + b, + B, + if effective_lowband != -1 { + norm.offset(effective_lowband as isize) + } else { + NULL as *mut celt_norm + }, + LM, + if last != 0 { + NULL as *mut celt_norm + } else { + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + }, + lowband_scratch, + (x_cm | y_cm) as i32, + ); + } + } else { + x_cm = quant_band( + &mut ctx, + X, + N, + b, + B, + if effective_lowband != -1 { + norm.offset(effective_lowband as isize) + } else { + NULL as *mut celt_norm + }, + LM, + if last != 0 { + NULL as *mut celt_norm + } else { + norm.offset((M * *eBands.offset(i as isize) as i32) as isize) + .offset(-(norm_offset as isize)) + }, + Q15ONE, + lowband_scratch, + (x_cm | y_cm) as i32, + ); + } + y_cm = x_cm; + } + *collapse_masks.offset((i * C + 0) as isize) = x_cm as u8; + *collapse_masks.offset((i * C + C - 1) as isize) = y_cm as u8; + balance += *pulses.offset(i as isize) + tell; + update_lowband = (b > N << BITRES) as i32; + ctx.avoid_split_noise = 0; + i += 1; + } + *seed = ctx.seed; +} diff --git a/vendor/unsafe-libopus/src/celt/celt.rs b/vendor/unsafe-libopus/src/celt/celt.rs new file mode 100644 index 00000000..c927d8b8 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/celt.rs @@ -0,0 +1,224 @@ +use crate::celt::modes::OpusCustomMode; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; +} + +pub use self::arch_h::{opus_val16, opus_val32}; +use crate::externs::memmove; + +pub static trim_icdf: [u8; 11] = [126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0]; +pub static spread_icdf: [u8; 4] = [25, 23, 2, 0]; +pub static tapset_icdf: [u8; 3] = [2, 1, 0]; +pub static tf_select_table: [[i8; 8]; 4] = [ + [0, -1, 0, -1, 0, -1, 0, -1], + [0, -1, 0, -2, 1, 0, 1, -1], + [0, -2, 0, -3, 2, 0, 1, -1], + [0, -2, 0, -3, 3, 0, 1, -1], +]; + +pub const OPUS_SET_ENERGY_MASK_REQUEST: i32 = 10026; +pub const CELT_GET_MODE_REQUEST: i32 = 10015; +pub const CELT_SET_SILK_INFO_REQUEST: i32 = 10028; +pub const CELT_SET_ANALYSIS_REQUEST: i32 = 10022; +pub const CELT_SET_SIGNALLING_REQUEST: i32 = 10016; +pub const OPUS_SET_LFE_REQUEST: i32 = 10024; +pub const CELT_SET_START_BAND_REQUEST: i32 = 10010; +pub const CELT_SET_CHANNELS_REQUEST: i32 = 10008; +pub const CELT_SET_END_BAND_REQUEST: i32 = 10012; +pub const CELT_SET_PREDICTION_REQUEST: i32 = 10002; +pub const CELT_GET_AND_CLEAR_ERROR_REQUEST: i32 = 10007; + +pub const COMBFILTER_MAXPERIOD: i32 = 1024; +pub const COMBFILTER_MINPERIOD: i32 = 15; + +pub fn resampling_factor(rate: i32) -> i32 { + match rate { + 48000 => 1, + 24000 => 2, + 16000 => 3, + 12000 => 4, + 8000 => 6, + _ => panic!("Unsupported sampling rate: {}", rate), + } +} +unsafe fn comb_filter_const_c( + y: *mut opus_val32, + x: *mut opus_val32, + T: i32, + N: i32, + g10: opus_val16, + g11: opus_val16, + g12: opus_val16, +) { + let mut x0: opus_val32 = 0.; + let mut x1: opus_val32 = 0.; + let mut x2: opus_val32 = 0.; + let mut x3: opus_val32 = 0.; + let mut x4: opus_val32 = 0.; + let mut i: i32 = 0; + x4 = *x.offset((-T - 2) as isize); + x3 = *x.offset((-T - 1) as isize); + x2 = *x.offset(-T as isize); + x1 = *x.offset((-T + 1) as isize); + i = 0; + while i < N { + x0 = *x.offset((i - T + 2) as isize); + *y.offset(i as isize) = + *x.offset(i as isize) + g10 * x2 + g11 * (x1 + x3) + g12 * (x0 + x4); + *y.offset(i as isize) = *y.offset(i as isize); + x4 = x3; + x3 = x2; + x2 = x1; + x1 = x0; + i += 1; + } +} +pub unsafe fn comb_filter( + y: *mut opus_val32, + x: *mut opus_val32, + mut T0: i32, + mut T1: i32, + N: i32, + g0: opus_val16, + g1: opus_val16, + tapset0: i32, + tapset1: i32, + window: *const opus_val16, + mut overlap: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut g00: opus_val16 = 0.; + let mut g01: opus_val16 = 0.; + let mut g02: opus_val16 = 0.; + let mut g10: opus_val16 = 0.; + let mut g11: opus_val16 = 0.; + let mut g12: opus_val16 = 0.; + let mut x0: opus_val32 = 0.; + let mut x1: opus_val32 = 0.; + let mut x2: opus_val32 = 0.; + let mut x3: opus_val32 = 0.; + let mut x4: opus_val32 = 0.; + static mut gains: [[opus_val16; 3]; 3] = [ + [0.3066406250f32, 0.2170410156f32, 0.1296386719f32], + [0.4638671875f32, 0.2680664062f32, 0.0f32], + [0.7998046875f32, 0.1000976562f32, 0.0f32], + ]; + if g0 == 0 as f32 && g1 == 0 as f32 { + if x != y { + memmove( + y as *mut core::ffi::c_void, + x as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * y.offset_from(x) as i64) as u64), + ); + } + return; + } + T0 = if T0 > 15 { T0 } else { 15 }; + T1 = if T1 > 15 { T1 } else { 15 }; + g00 = g0 * gains[tapset0 as usize][0 as usize]; + g01 = g0 * gains[tapset0 as usize][1 as usize]; + g02 = g0 * gains[tapset0 as usize][2 as usize]; + g10 = g1 * gains[tapset1 as usize][0 as usize]; + g11 = g1 * gains[tapset1 as usize][1 as usize]; + g12 = g1 * gains[tapset1 as usize][2 as usize]; + x1 = *x.offset((-T1 + 1) as isize); + x2 = *x.offset(-T1 as isize); + x3 = *x.offset((-T1 - 1) as isize); + x4 = *x.offset((-T1 - 2) as isize); + if g0 == g1 && T0 == T1 && tapset0 == tapset1 { + overlap = 0; + } + i = 0; + while i < overlap { + let mut f: opus_val16 = 0.; + x0 = *x.offset((i - T1 + 2) as isize); + f = *window.offset(i as isize) * *window.offset(i as isize); + *y.offset(i as isize) = *x.offset(i as isize) + + (1.0f32 - f) * g00 * *x.offset((i - T0) as isize) + + (1.0f32 - f) + * g01 + * (*x.offset((i - T0 + 1) as isize) + *x.offset((i - T0 - 1) as isize)) + + (1.0f32 - f) + * g02 + * (*x.offset((i - T0 + 2) as isize) + *x.offset((i - T0 - 2) as isize)) + + f * g10 * x2 + + f * g11 * (x1 + x3) + + f * g12 * (x0 + x4); + *y.offset(i as isize) = *y.offset(i as isize); + x4 = x3; + x3 = x2; + x2 = x1; + x1 = x0; + i += 1; + } + if g1 == 0 as f32 { + if x != y { + memmove( + y.offset(overlap as isize) as *mut core::ffi::c_void, + x.offset(overlap as isize) as *const core::ffi::c_void, + ((N - overlap) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * y + .offset(overlap as isize) + .offset_from(x.offset(overlap as isize)) + as i64) as u64, + ), + ); + } + return; + } + comb_filter_const_c( + y.offset(i as isize), + x.offset(i as isize), + T1, + N - i, + g10, + g11, + g12, + ); +} +pub unsafe fn init_caps(m: *const OpusCustomMode, cap: *mut i32, LM: i32, C: i32) { + let mut i: i32 = 0; + i = 0; + while i < (*m).nbEBands { + let mut N: i32 = 0; + N = (*((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32) + << LM; + *cap.offset(i as isize) = + (*((*m).cache.caps).offset(((*m).nbEBands * (2 * LM + C - 1) + i) as isize) as i32 + + 64) + * C + * N + >> 2; + i += 1; + } +} + +pub fn opus_strerror(error: i32) -> &'static str { + static error_strings: [&str; 8] = [ + "success (0)", + "invalid argument (-1)", + "buffer too small (-2)", + "internal error (-3)", + "corrupted stream (-4)", + "request not implemented (-5)", + "invalid state (-6)", + "memory allocation failed (-7)", + ]; + if error > 0 || error < -7 { + "unknown error" + } else { + error_strings[-error as usize] + } +} + +pub fn opus_get_version_string() -> &'static str { + "unsafe-libopus (rust port) 1.3.1" +} diff --git a/vendor/unsafe-libopus/src/celt/celt_decoder.rs b/vendor/unsafe-libopus/src/celt/celt_decoder.rs new file mode 100644 index 00000000..76541df2 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/celt_decoder.rs @@ -0,0 +1,1570 @@ +use crate::celt::bands::{ + anti_collapse, celt_lcg_rand, denormalise_bands, quant_all_bands, SPREAD_NORMAL, +}; +use crate::opus_custom_decoder_ctl; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub type celt_sig = f32; + pub type celt_norm = f32; + pub type celt_ener = f32; + pub const Q15ONE: f32 = 1.0f32; + pub const VERY_SMALL: f32 = 1e-30f32; + pub const CELT_SIG_SCALE: f32 = 32768.0f32; +} + +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub mod stddef_h { + pub const NULL: i32 = 0; +} +pub use self::arch_h::{ + celt_ener, celt_norm, celt_sig, opus_val16, opus_val32, CELT_SIG_SCALE, Q15ONE, VERY_SMALL, +}; +pub use self::cpu_support_h::opus_select_arch; +pub use self::stddef_h::NULL; +use crate::celt::celt::{ + comb_filter, init_caps, resampling_factor, spread_icdf, tapset_icdf, tf_select_table, trim_icdf, +}; +use crate::celt::celt::{ + CELT_GET_AND_CLEAR_ERROR_REQUEST, CELT_GET_MODE_REQUEST, CELT_SET_CHANNELS_REQUEST, + CELT_SET_END_BAND_REQUEST, CELT_SET_SIGNALLING_REQUEST, CELT_SET_START_BAND_REQUEST, +}; +use crate::celt::celt_lpc::{_celt_autocorr, _celt_lpc, celt_fir_c, celt_iir, LPC_ORDER}; +use crate::celt::entcode::{ec_get_error, ec_tell, ec_tell_frac, BITRES}; +use crate::celt::entdec::{ + ec_dec, ec_dec_bit_logp, ec_dec_bits, ec_dec_icdf, ec_dec_init, ec_dec_uint, +}; +use crate::celt::mathops::celt_sqrt; +use crate::celt::mdct::clt_mdct_backward_c; +use crate::celt::modes::{opus_custom_mode_create, OpusCustomMode, MAX_PERIOD}; +use crate::celt::pitch::{pitch_downsample, pitch_search}; +use crate::celt::quant_bands::{ + unquant_coarse_energy, unquant_energy_finalise, unquant_fine_energy, +}; +use crate::celt::rate::clt_compute_allocation; +use crate::celt::vq::renormalise_vector; +use crate::externs::{memcpy, memmove, memset}; +use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_LOOKAHEAD_REQUEST, + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PITCH_REQUEST, OPUS_INTERNAL_ERROR, + OPUS_OK, OPUS_RESET_STATE, OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_UNIMPLEMENTED, +}; +use crate::varargs::VarArgs; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusCustomDecoder { + pub mode: *const OpusCustomMode, + pub overlap: i32, + pub channels: i32, + pub stream_channels: i32, + pub downsample: i32, + pub start: i32, + pub end: i32, + pub signalling: i32, + pub disable_inv: i32, + pub arch: i32, + pub rng: u32, + pub error: i32, + pub last_pitch_index: i32, + pub loss_count: i32, + pub skip_plc: i32, + pub postfilter_period: i32, + pub postfilter_period_old: i32, + pub postfilter_gain: opus_val16, + pub postfilter_gain_old: opus_val16, + pub postfilter_tapset: i32, + pub postfilter_tapset_old: i32, + pub preemph_memD: [celt_sig; 2], + pub _decode_mem: [celt_sig; 1], +} +pub const PLC_PITCH_LAG_MAX: i32 = 720; +pub const PLC_PITCH_LAG_MIN: i32 = 100; +pub const DECODE_BUFFER_SIZE: i32 = 2048; +pub unsafe fn validate_celt_decoder(st: *mut OpusCustomDecoder) { + assert!( + (*st).mode == opus_custom_mode_create(48000, 960, 0 as *mut i32) as *const OpusCustomMode + ); + assert!((*st).overlap == 120); + assert!((*st).channels == 1 || (*st).channels == 2); + assert!((*st).stream_channels == 1 || (*st).stream_channels == 2); + assert!((*st).downsample > 0); + assert!((*st).start == 0 || (*st).start == 17); + assert!((*st).start < (*st).end); + assert!((*st).end <= 21); + assert!((*st).arch >= 0); + assert!((*st).arch <= 0); + assert!((*st).last_pitch_index <= 720); + assert!((*st).last_pitch_index >= 100 || (*st).last_pitch_index == 0); + assert!((*st).postfilter_period < 1024); + assert!((*st).postfilter_period >= 15 || (*st).postfilter_period == 0); + assert!((*st).postfilter_period_old < 1024); + assert!((*st).postfilter_period_old >= 15 || (*st).postfilter_period_old == 0); + assert!((*st).postfilter_tapset <= 2); + assert!((*st).postfilter_tapset >= 0); + assert!((*st).postfilter_tapset_old <= 2); + assert!((*st).postfilter_tapset_old >= 0); +} +pub unsafe fn celt_decoder_get_size(channels: i32) -> i32 { + let mode: *const OpusCustomMode = opus_custom_mode_create(48000, 960, NULL as *mut i32); + return opus_custom_decoder_get_size(mode, channels); +} +#[inline] +unsafe fn opus_custom_decoder_get_size(mode: *const OpusCustomMode, channels: i32) -> i32 { + let size: i32 = (::core::mem::size_of::() as u64) + .wrapping_add( + ((channels * (DECODE_BUFFER_SIZE + (*mode).overlap) - 1) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) + .wrapping_add( + ((channels * LPC_ORDER) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) + .wrapping_add( + ((4 * 2 * (*mode).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as i32; + return size; +} +pub unsafe fn celt_decoder_init( + st: *mut OpusCustomDecoder, + sampling_rate: i32, + channels: i32, +) -> i32 { + let mut ret: i32 = 0; + ret = opus_custom_decoder_init( + st, + opus_custom_mode_create(48000, 960, NULL as *mut i32), + channels, + ); + if ret != OPUS_OK { + return ret; + } + (*st).downsample = resampling_factor(sampling_rate); + if (*st).downsample == 0 { + return OPUS_BAD_ARG; + } else { + return OPUS_OK; + }; +} +#[inline] +unsafe fn opus_custom_decoder_init( + st: *mut OpusCustomDecoder, + mode: *const OpusCustomMode, + channels: i32, +) -> i32 { + if channels < 0 || channels > 2 { + return OPUS_BAD_ARG; + } + if st.is_null() { + return OPUS_ALLOC_FAIL; + } + memset( + st as *mut i8 as *mut core::ffi::c_void, + 0, + (opus_custom_decoder_get_size(mode, channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + (*st).mode = mode; + (*st).overlap = (*mode).overlap; + (*st).channels = channels; + (*st).stream_channels = (*st).channels; + (*st).downsample = 1; + (*st).start = 0; + (*st).end = (*(*st).mode).effEBands; + (*st).signalling = 1; + (*st).disable_inv = (channels == 1) as i32; + (*st).arch = opus_select_arch(); + opus_custom_decoder_ctl!(st, OPUS_RESET_STATE); + return OPUS_OK; +} +unsafe fn deemphasis_stereo_simple( + in_0: *mut *mut celt_sig, + pcm: *mut opus_val16, + N: i32, + coef0: opus_val16, + mem: *mut celt_sig, +) { + let mut x0: *mut celt_sig = 0 as *mut celt_sig; + let mut x1: *mut celt_sig = 0 as *mut celt_sig; + let mut m0: celt_sig = 0.; + let mut m1: celt_sig = 0.; + let mut j: i32 = 0; + x0 = *in_0.offset(0 as isize); + x1 = *in_0.offset(1 as isize); + m0 = *mem.offset(0 as isize); + m1 = *mem.offset(1 as isize); + j = 0; + while j < N { + let mut tmp0: celt_sig = 0.; + let mut tmp1: celt_sig = 0.; + tmp0 = *x0.offset(j as isize) + VERY_SMALL + m0; + tmp1 = *x1.offset(j as isize) + VERY_SMALL + m1; + m0 = coef0 * tmp0; + m1 = coef0 * tmp1; + *pcm.offset((2 * j) as isize) = tmp0 * (1 as f32 / CELT_SIG_SCALE); + *pcm.offset((2 * j + 1) as isize) = tmp1 * (1 as f32 / CELT_SIG_SCALE); + j += 1; + } + *mem.offset(0 as isize) = m0; + *mem.offset(1 as isize) = m1; +} +unsafe fn deemphasis( + in_0: *mut *mut celt_sig, + pcm: *mut opus_val16, + N: i32, + C: i32, + downsample: i32, + coef: *const opus_val16, + mem: *mut celt_sig, + accum: i32, +) { + let mut c: i32 = 0; + let mut Nd: i32 = 0; + let mut apply_downsampling: i32 = 0; + let mut coef0: opus_val16 = 0.; + if downsample == 1 && C == 2 && accum == 0 { + deemphasis_stereo_simple(in_0, pcm, N, *coef.offset(0 as isize), mem); + return; + } + assert!(accum == 0); + let vla = N as usize; + let mut scratch: Vec = ::std::vec::from_elem(0., vla); + coef0 = *coef.offset(0 as isize); + Nd = N / downsample; + c = 0; + loop { + let mut j: i32 = 0; + let mut x: *mut celt_sig = 0 as *mut celt_sig; + let mut y: *mut opus_val16 = 0 as *mut opus_val16; + let mut m: celt_sig = *mem.offset(c as isize); + x = *in_0.offset(c as isize); + y = pcm.offset(c as isize); + if downsample > 1 { + j = 0; + while j < N { + let tmp: celt_sig = *x.offset(j as isize) + VERY_SMALL + m; + m = coef0 * tmp; + *scratch.as_mut_ptr().offset(j as isize) = tmp; + j += 1; + } + apply_downsampling = 1; + } else { + j = 0; + while j < N { + let tmp_0: celt_sig = *x.offset(j as isize) + VERY_SMALL + m; + m = coef0 * tmp_0; + *y.offset((j * C) as isize) = tmp_0 * (1 as f32 / CELT_SIG_SCALE); + j += 1; + } + } + *mem.offset(c as isize) = m; + if apply_downsampling != 0 { + j = 0; + while j < Nd { + *y.offset((j * C) as isize) = + *scratch.as_mut_ptr().offset((j * downsample) as isize) + * (1 as f32 / CELT_SIG_SCALE); + j += 1; + } + } + c += 1; + if !(c < C) { + break; + } + } +} +unsafe fn celt_synthesis( + mode: *const OpusCustomMode, + X: *mut celt_norm, + out_syn: *mut *mut celt_sig, + oldBandE: *mut opus_val16, + start: i32, + effEnd: i32, + C: i32, + CC: i32, + isTransient: i32, + LM: i32, + downsample: i32, + silence: i32, + arch: i32, +) { + let mut c: i32 = 0; + let mut i: i32 = 0; + let mut M: i32 = 0; + let mut b: i32 = 0; + let mut B: i32 = 0; + let mut N: i32 = 0; + let mut NB: i32 = 0; + let mut shift: i32 = 0; + let mut nbEBands: i32 = 0; + let mut overlap: i32 = 0; + overlap = (*mode).overlap; + nbEBands = (*mode).nbEBands; + N = (*mode).shortMdctSize << LM; + let vla = N as usize; + let mut freq: Vec = ::std::vec::from_elem(0., vla); + M = (1) << LM; + if isTransient != 0 { + B = M; + NB = (*mode).shortMdctSize; + shift = (*mode).maxLM; + } else { + B = 1; + NB = (*mode).shortMdctSize << LM; + shift = (*mode).maxLM - LM; + } + if CC == 2 && C == 1 { + let mut freq2: *mut celt_sig = 0 as *mut celt_sig; + denormalise_bands( + mode, + X, + freq.as_mut_ptr(), + oldBandE, + start, + effEnd, + M, + downsample, + silence, + ); + freq2 = (*out_syn.offset(1 as isize)).offset((overlap / 2) as isize); + memcpy( + freq2 as *mut core::ffi::c_void, + freq.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * freq2.offset_from(freq.as_mut_ptr()) as i64) as u64), + ); + b = 0; + while b < B { + clt_mdct_backward_c( + &(*mode).mdct, + &mut *freq2.offset(b as isize), + (*out_syn.offset(0 as isize)).offset((NB * b) as isize), + (*mode).window, + overlap, + shift, + B, + arch, + ); + b += 1; + } + b = 0; + while b < B { + clt_mdct_backward_c( + &(*mode).mdct, + &mut *freq.as_mut_ptr().offset(b as isize), + (*out_syn.offset(1 as isize)).offset((NB * b) as isize), + (*mode).window, + overlap, + shift, + B, + arch, + ); + b += 1; + } + } else if CC == 1 && C == 2 { + let mut freq2_0: *mut celt_sig = 0 as *mut celt_sig; + freq2_0 = (*out_syn.offset(0 as isize)).offset((overlap / 2) as isize); + denormalise_bands( + mode, + X, + freq.as_mut_ptr(), + oldBandE, + start, + effEnd, + M, + downsample, + silence, + ); + denormalise_bands( + mode, + X.offset(N as isize), + freq2_0, + oldBandE.offset(nbEBands as isize), + start, + effEnd, + M, + downsample, + silence, + ); + i = 0; + while i < N { + *freq.as_mut_ptr().offset(i as isize) = 0.5f32 * *freq.as_mut_ptr().offset(i as isize) + + 0.5f32 * *freq2_0.offset(i as isize); + i += 1; + } + b = 0; + while b < B { + clt_mdct_backward_c( + &(*mode).mdct, + &mut *freq.as_mut_ptr().offset(b as isize), + (*out_syn.offset(0 as isize)).offset((NB * b) as isize), + (*mode).window, + overlap, + shift, + B, + arch, + ); + b += 1; + } + } else { + c = 0; + loop { + denormalise_bands( + mode, + X.offset((c * N) as isize), + freq.as_mut_ptr(), + oldBandE.offset((c * nbEBands) as isize), + start, + effEnd, + M, + downsample, + silence, + ); + b = 0; + while b < B { + clt_mdct_backward_c( + &(*mode).mdct, + &mut *freq.as_mut_ptr().offset(b as isize), + (*out_syn.offset(c as isize)).offset((NB * b) as isize), + (*mode).window, + overlap, + shift, + B, + arch, + ); + b += 1; + } + c += 1; + if !(c < CC) { + break; + } + } + } + c = 0; + loop { + i = 0; + while i < N { + *(*out_syn.offset(c as isize)).offset(i as isize) = + *(*out_syn.offset(c as isize)).offset(i as isize); + i += 1; + } + c += 1; + if !(c < CC) { + break; + } + } +} +unsafe fn tf_decode( + start: i32, + end: i32, + isTransient: i32, + tf_res: *mut i32, + LM: i32, + dec: &mut ec_dec, +) { + let mut i: i32 = 0; + let mut curr: i32 = 0; + let mut tf_select: i32 = 0; + let mut tf_select_rsv: i32 = 0; + let mut tf_changed: i32 = 0; + let mut logp: i32 = 0; + let mut budget: u32 = 0; + let mut tell: u32 = 0; + budget = dec.storage.wrapping_mul(8); + tell = ec_tell(dec) as u32; + logp = if isTransient != 0 { 2 } else { 4 }; + tf_select_rsv = (LM > 0 && tell.wrapping_add(logp as u32).wrapping_add(1) <= budget) as i32; + budget = budget.wrapping_sub(tf_select_rsv as u32); + curr = 0; + tf_changed = curr; + i = start; + while i < end { + if tell.wrapping_add(logp as u32) <= budget { + curr ^= ec_dec_bit_logp(dec, logp as u32); + tell = ec_tell(dec) as u32; + tf_changed |= curr; + } + *tf_res.offset(i as isize) = curr; + logp = if isTransient != 0 { 4 } else { 5 }; + i += 1; + } + tf_select = 0; + if tf_select_rsv != 0 + && tf_select_table[LM as usize][(4 * isTransient + 0 + tf_changed) as usize] as i32 + != tf_select_table[LM as usize][(4 * isTransient + 2 + tf_changed) as usize] as i32 + { + tf_select = ec_dec_bit_logp(dec, 1); + } + i = start; + while i < end { + *tf_res.offset(i as isize) = tf_select_table[LM as usize] + [(4 * isTransient + 2 * tf_select + *tf_res.offset(i as isize)) as usize] + as i32; + i += 1; + } +} +unsafe fn celt_plc_pitch_search(decode_mem: *mut *mut celt_sig, C: i32, arch: i32) -> i32 { + let mut pitch_index: i32 = 0; + let mut lp_pitch_buf: [opus_val16; 1024] = [0.; 1024]; + pitch_downsample( + decode_mem as *mut *mut celt_sig, + lp_pitch_buf.as_mut_ptr(), + DECODE_BUFFER_SIZE, + C, + arch, + ); + pitch_search( + lp_pitch_buf + .as_mut_ptr() + .offset((PLC_PITCH_LAG_MAX >> 1) as isize), + lp_pitch_buf.as_mut_ptr(), + DECODE_BUFFER_SIZE - PLC_PITCH_LAG_MAX, + PLC_PITCH_LAG_MAX - PLC_PITCH_LAG_MIN, + &mut pitch_index, + arch, + ); + pitch_index = PLC_PITCH_LAG_MAX - pitch_index; + return pitch_index; +} +unsafe fn celt_decode_lost(st: *mut OpusCustomDecoder, N: i32, LM: i32) { + let mut c: i32 = 0; + let mut i: i32 = 0; + let C: i32 = (*st).channels; + let mut decode_mem: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2]; + let mut out_syn: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2]; + let mut lpc: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16; + let mut backgroundLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut nbEBands: i32 = 0; + let mut overlap: i32 = 0; + let mut start: i32 = 0; + let mut loss_count: i32 = 0; + let mut noise_based: i32 = 0; + let mut eBands: *const i16 = 0 as *const i16; + mode = (*st).mode; + nbEBands = (*mode).nbEBands; + overlap = (*mode).overlap; + eBands = (*mode).eBands; + c = 0; + loop { + decode_mem[c as usize] = ((*st)._decode_mem) + .as_mut_ptr() + .offset((c * (DECODE_BUFFER_SIZE + overlap)) as isize); + out_syn[c as usize] = (decode_mem[c as usize]) + .offset(DECODE_BUFFER_SIZE as isize) + .offset(-(N as isize)); + c += 1; + if !(c < C) { + break; + } + } + lpc = ((*st)._decode_mem) + .as_mut_ptr() + .offset(((DECODE_BUFFER_SIZE + overlap) * C) as isize) as *mut opus_val16; + oldBandE = lpc.offset((C * LPC_ORDER) as isize); + oldLogE = oldBandE.offset((2 * nbEBands) as isize); + oldLogE2 = oldLogE.offset((2 * nbEBands) as isize); + backgroundLogE = oldLogE2.offset((2 * nbEBands) as isize); + loss_count = (*st).loss_count; + start = (*st).start; + noise_based = (loss_count >= 5 || start != 0 || (*st).skip_plc != 0) as i32; + if noise_based != 0 { + let mut seed: u32 = 0; + let mut end: i32 = 0; + let mut effEnd: i32 = 0; + let mut decay: opus_val16 = 0.; + end = (*st).end; + effEnd = if start + > (if end < (*mode).effEBands { + end + } else { + (*mode).effEBands + }) { + start + } else if end < (*mode).effEBands { + end + } else { + (*mode).effEBands + }; + let vla = (C * N) as usize; + let mut X: Vec = ::std::vec::from_elem(0., vla); + decay = if loss_count == 0 { 1.5f32 } else { 0.5f32 }; + c = 0; + loop { + i = start; + while i < end { + *oldBandE.offset((c * nbEBands + i) as isize) = if *backgroundLogE + .offset((c * nbEBands + i) as isize) + > *oldBandE.offset((c * nbEBands + i) as isize) - decay + { + *backgroundLogE.offset((c * nbEBands + i) as isize) + } else { + *oldBandE.offset((c * nbEBands + i) as isize) - decay + }; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + seed = (*st).rng; + c = 0; + while c < C { + i = start; + while i < effEnd { + let mut j: i32 = 0; + let mut boffs: i32 = 0; + let mut blen: i32 = 0; + boffs = N * c + ((*eBands.offset(i as isize) as i32) << LM); + blen = (*eBands.offset((i + 1) as isize) as i32 + - *eBands.offset(i as isize) as i32) + << LM; + j = 0; + while j < blen { + seed = celt_lcg_rand(seed); + *X.as_mut_ptr().offset((boffs + j) as isize) = (seed as i32 >> 20) as celt_norm; + j += 1; + } + renormalise_vector( + X.as_mut_ptr().offset(boffs as isize), + blen, + Q15ONE, + (*st).arch, + ); + i += 1; + } + c += 1; + } + (*st).rng = seed; + c = 0; + loop { + memmove( + decode_mem[c as usize] as *mut core::ffi::c_void, + (decode_mem[c as usize]).offset(N as isize) as *const core::ffi::c_void, + ((2048 - N + (overlap >> 1)) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (decode_mem[c as usize]) + .offset_from((decode_mem[c as usize]).offset(N as isize)) + as i64) as u64, + ), + ); + c += 1; + if !(c < C) { + break; + } + } + celt_synthesis( + mode, + X.as_mut_ptr(), + out_syn.as_mut_ptr(), + oldBandE, + start, + effEnd, + C, + C, + 0, + LM, + (*st).downsample, + 0, + (*st).arch, + ); + } else { + let mut exc_length: i32 = 0; + let mut window: *const opus_val16 = 0 as *const opus_val16; + let mut exc: *mut opus_val16 = 0 as *mut opus_val16; + let mut fade: opus_val16 = Q15ONE; + let mut pitch_index: i32 = 0; + if loss_count == 0 { + pitch_index = celt_plc_pitch_search(decode_mem.as_mut_ptr(), C, (*st).arch); + (*st).last_pitch_index = pitch_index; + } else { + pitch_index = (*st).last_pitch_index; + fade = 0.8f32; + } + exc_length = if 2 * pitch_index < 1024 { + 2 * pitch_index + } else { + 1024 + }; + let vla_0 = overlap as usize; + let mut etmp: Vec = ::std::vec::from_elem(0., vla_0); + let mut _exc: [opus_val16; 1048] = [0.; 1048]; + let vla_1 = exc_length as usize; + let mut fir_tmp: Vec = ::std::vec::from_elem(0., vla_1); + exc = _exc.as_mut_ptr().offset(LPC_ORDER as isize); + window = (*mode).window; + c = 0; + loop { + let mut decay_0: opus_val16 = 0.; + let mut attenuation: opus_val16 = 0.; + let mut S1: opus_val32 = 0 as opus_val32; + let mut buf: *mut celt_sig = 0 as *mut celt_sig; + let mut extrapolation_offset: i32 = 0; + let mut extrapolation_len: i32 = 0; + let mut j_0: i32 = 0; + buf = decode_mem[c as usize]; + i = 0; + while i < MAX_PERIOD + LPC_ORDER { + *exc.offset((i - LPC_ORDER) as isize) = + *buf.offset((2048 - 1024 - 24 + i) as isize); + i += 1; + } + if loss_count == 0 { + let mut ac: [opus_val32; 25] = [0.; 25]; + _celt_autocorr( + exc, + ac.as_mut_ptr(), + window, + overlap, + LPC_ORDER, + MAX_PERIOD, + (*st).arch, + ); + ac[0 as usize] *= 1.0001f32; + i = 1; + while i <= LPC_ORDER { + ac[i as usize] -= ac[i as usize] * (0.008f32 * 0.008f32) * i as f32 * i as f32; + i += 1; + } + _celt_lpc( + lpc.offset((c * LPC_ORDER) as isize), + ac.as_mut_ptr(), + LPC_ORDER, + ); + } + celt_fir_c( + exc.offset(1024 as isize).offset(-(exc_length as isize)), + lpc.offset((c * 24) as isize), + fir_tmp.as_mut_ptr(), + exc_length, + 24, + (*st).arch, + ); + memcpy( + exc.offset(1024 as isize).offset(-(exc_length as isize)) as *mut core::ffi::c_void, + fir_tmp.as_mut_ptr() as *const core::ffi::c_void, + (exc_length as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * exc + .offset(1024 as isize) + .offset(-(exc_length as isize)) + .offset_from(fir_tmp.as_mut_ptr()) as i64) + as u64, + ), + ); + let mut E1: opus_val32 = 1 as opus_val32; + let mut E2: opus_val32 = 1 as opus_val32; + let mut decay_length: i32 = 0; + decay_length = exc_length >> 1; + i = 0; + while i < decay_length { + let mut e: opus_val16 = 0.; + e = *exc.offset((MAX_PERIOD - decay_length + i) as isize); + E1 += e * e; + e = *exc.offset((MAX_PERIOD - 2 * decay_length + i) as isize); + E2 += e * e; + i += 1; + } + E1 = if E1 < E2 { E1 } else { E2 }; + decay_0 = celt_sqrt(E1 / E2); + memmove( + buf as *mut core::ffi::c_void, + buf.offset(N as isize) as *const core::ffi::c_void, + ((2048 - N) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * buf.offset_from(buf.offset(N as isize)) as i64) as u64), + ); + extrapolation_offset = MAX_PERIOD - pitch_index; + extrapolation_len = N + overlap; + attenuation = fade * decay_0; + j_0 = 0; + i = j_0; + while i < extrapolation_len { + let mut tmp: opus_val16 = 0.; + if j_0 >= pitch_index { + j_0 -= pitch_index; + attenuation = attenuation * decay_0; + } + *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) = + attenuation * *exc.offset((extrapolation_offset + j_0) as isize); + tmp = *buf.offset((2048 - 1024 - N + extrapolation_offset + j_0) as isize); + S1 += tmp * tmp; + i += 1; + j_0 += 1; + } + let mut lpc_mem: [opus_val16; 24] = [0.; 24]; + i = 0; + while i < LPC_ORDER { + lpc_mem[i as usize] = *buf.offset((2048 - N - 1 - i) as isize); + i += 1; + } + celt_iir( + buf.offset(DECODE_BUFFER_SIZE as isize) + .offset(-(N as isize)), + lpc.offset((c * LPC_ORDER) as isize), + buf.offset(DECODE_BUFFER_SIZE as isize) + .offset(-(N as isize)), + extrapolation_len, + LPC_ORDER, + lpc_mem.as_mut_ptr(), + (*st).arch, + ); + let mut S2: opus_val32 = 0 as opus_val32; + i = 0; + while i < extrapolation_len { + let tmp_0: opus_val16 = *buf.offset((2048 - N + i) as isize); + S2 += tmp_0 * tmp_0; + i += 1; + } + if !(S1 > 0.2f32 * S2) { + i = 0; + while i < extrapolation_len { + *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) = 0 as celt_sig; + i += 1; + } + } else if S1 < S2 { + let ratio: opus_val16 = celt_sqrt((S1 + 1 as f32) / (S2 + 1 as f32)); + i = 0; + while i < overlap { + let tmp_g: opus_val16 = Q15ONE - *window.offset(i as isize) * (1.0f32 - ratio); + *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) = + tmp_g * *buf.offset((2048 - N + i) as isize); + i += 1; + } + i = overlap; + while i < extrapolation_len { + *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) = + ratio * *buf.offset((2048 - N + i) as isize); + i += 1; + } + } + comb_filter( + etmp.as_mut_ptr(), + buf.offset(DECODE_BUFFER_SIZE as isize), + (*st).postfilter_period, + (*st).postfilter_period, + overlap, + -(*st).postfilter_gain, + -(*st).postfilter_gain, + (*st).postfilter_tapset, + (*st).postfilter_tapset, + NULL as *const opus_val16, + 0, + (*st).arch, + ); + i = 0; + while i < overlap / 2 { + *buf.offset((DECODE_BUFFER_SIZE + i) as isize) = *window.offset(i as isize) + * *etmp.as_mut_ptr().offset((overlap - 1 - i) as isize) + + *window.offset((overlap - i - 1) as isize) + * *etmp.as_mut_ptr().offset(i as isize); + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + } + (*st).loss_count = loss_count + 1; +} +pub unsafe fn celt_decode_with_ec( + st: *mut OpusCustomDecoder, + data: *const u8, + len: i32, + pcm: *mut opus_val16, + mut frame_size: i32, + dec: Option<&mut ec_dec>, + accum: i32, +) -> i32 { + let mut c: i32 = 0; + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut spread_decision: i32 = 0; + let mut bits: i32 = 0; + let mut _dec: ec_dec = ec_dec { + buf: &mut [], + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut decode_mem: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2]; + let mut out_syn: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2]; + let mut lpc: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16; + let mut backgroundLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut shortBlocks: i32 = 0; + let mut isTransient: i32 = 0; + let mut intra_ener: i32 = 0; + let CC: i32 = (*st).channels; + let mut LM: i32 = 0; + let mut M: i32 = 0; + let mut start: i32 = 0; + let mut end: i32 = 0; + let mut effEnd: i32 = 0; + let mut codedBands: i32 = 0; + let mut alloc_trim: i32 = 0; + let mut postfilter_pitch: i32 = 0; + let mut postfilter_gain: opus_val16 = 0.; + let mut intensity: i32 = 0; + let mut dual_stereo: i32 = 0; + let mut total_bits: i32 = 0; + let mut balance: i32 = 0; + let mut tell: i32 = 0; + let mut dynalloc_logp: i32 = 0; + let mut postfilter_tapset: i32 = 0; + let mut anti_collapse_rsv: i32 = 0; + let mut anti_collapse_on: i32 = 0; + let mut silence: i32 = 0; + let C: i32 = (*st).stream_channels; + let mut mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut nbEBands: i32 = 0; + let mut overlap: i32 = 0; + let mut eBands: *const i16 = 0 as *const i16; + validate_celt_decoder(st); + mode = (*st).mode; + nbEBands = (*mode).nbEBands; + overlap = (*mode).overlap; + eBands = (*mode).eBands; + start = (*st).start; + end = (*st).end; + frame_size *= (*st).downsample; + lpc = ((*st)._decode_mem) + .as_mut_ptr() + .offset(((DECODE_BUFFER_SIZE + overlap) * CC) as isize) as *mut opus_val16; + oldBandE = lpc.offset((CC * LPC_ORDER) as isize); + oldLogE = oldBandE.offset((2 * nbEBands) as isize); + oldLogE2 = oldLogE.offset((2 * nbEBands) as isize); + backgroundLogE = oldLogE2.offset((2 * nbEBands) as isize); + LM = 0; + while LM <= (*mode).maxLM { + if (*mode).shortMdctSize << LM == frame_size { + break; + } + LM += 1; + } + if LM > (*mode).maxLM { + return OPUS_BAD_ARG; + } + M = (1) << LM; + if len < 0 || len > 1275 || pcm.is_null() { + return OPUS_BAD_ARG; + } + N = M * (*mode).shortMdctSize; + c = 0; + loop { + decode_mem[c as usize] = ((*st)._decode_mem) + .as_mut_ptr() + .offset((c * (DECODE_BUFFER_SIZE + overlap)) as isize); + out_syn[c as usize] = (decode_mem[c as usize]) + .offset(DECODE_BUFFER_SIZE as isize) + .offset(-(N as isize)); + c += 1; + if !(c < CC) { + break; + } + } + effEnd = end; + if effEnd > (*mode).effEBands { + effEnd = (*mode).effEBands; + } + if data.is_null() || len <= 1 { + celt_decode_lost(st, N, LM); + deemphasis( + out_syn.as_mut_ptr(), + pcm, + N, + CC, + (*st).downsample, + ((*mode).preemph).as_ptr(), + ((*st).preemph_memD).as_mut_ptr(), + accum, + ); + return frame_size / (*st).downsample; + } + (*st).skip_plc = ((*st).loss_count != 0) as i32; + let dec = if let Some(dec) = dec { + dec + } else { + _dec = ec_dec_init(std::slice::from_raw_parts_mut( + data as *mut u8, + len as usize, + )); + &mut _dec + }; + if C == 1 { + i = 0; + while i < nbEBands { + *oldBandE.offset(i as isize) = + if *oldBandE.offset(i as isize) > *oldBandE.offset((nbEBands + i) as isize) { + *oldBandE.offset(i as isize) + } else { + *oldBandE.offset((nbEBands + i) as isize) + }; + i += 1; + } + } + total_bits = len * 8; + tell = ec_tell(dec); + if tell >= total_bits { + silence = 1; + } else if tell == 1 { + silence = ec_dec_bit_logp(dec, 15); + } else { + silence = 0; + } + if silence != 0 { + tell = len * 8; + (*dec).nbits_total += tell - ec_tell(dec); + } + postfilter_gain = 0 as opus_val16; + postfilter_pitch = 0; + postfilter_tapset = 0; + if start == 0 && tell + 16 <= total_bits { + if ec_dec_bit_logp(dec, 1) != 0 { + let mut qg: i32 = 0; + let mut octave: i32 = 0; + octave = ec_dec_uint(dec, 6) as i32; + postfilter_pitch = (((16) << octave) as u32) + .wrapping_add(ec_dec_bits(dec, (4 + octave) as u32)) + .wrapping_sub(1) as i32; + qg = ec_dec_bits(dec, 3) as i32; + if ec_tell(dec) + 2 <= total_bits { + postfilter_tapset = ec_dec_icdf(dec, &tapset_icdf, 2); + } + postfilter_gain = 0.09375f32 * (qg + 1) as f32; + } + tell = ec_tell(dec); + } + if LM > 0 && tell + 3 <= total_bits { + isTransient = ec_dec_bit_logp(dec, 3); + tell = ec_tell(dec); + } else { + isTransient = 0; + } + if isTransient != 0 { + shortBlocks = M; + } else { + shortBlocks = 0; + } + intra_ener = if tell + 3 <= total_bits { + ec_dec_bit_logp(dec, 3) + } else { + 0 + }; + unquant_coarse_energy(mode, start, end, oldBandE, intra_ener, dec, C, LM); + let vla = nbEBands as usize; + let mut tf_res: Vec = ::std::vec::from_elem(0, vla); + tf_decode(start, end, isTransient, tf_res.as_mut_ptr(), LM, dec); + tell = ec_tell(dec); + spread_decision = SPREAD_NORMAL; + if tell + 4 <= total_bits { + spread_decision = ec_dec_icdf(dec, &spread_icdf, 5); + } + let vla_0 = nbEBands as usize; + let mut cap: Vec = ::std::vec::from_elem(0, vla_0); + init_caps(mode, cap.as_mut_ptr(), LM, C); + let vla_1 = nbEBands as usize; + let mut offsets: Vec = ::std::vec::from_elem(0, vla_1); + dynalloc_logp = 6; + total_bits <<= BITRES; + tell = ec_tell_frac(dec) as i32; + i = start; + while i < end { + let mut width: i32 = 0; + let mut quanta: i32 = 0; + let mut dynalloc_loop_logp: i32 = 0; + let mut boost: i32 = 0; + width = + C * (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32) << LM; + quanta = if (width << 3) < (if (6) << 3 > width { (6) << 3 } else { width }) { + width << 3 + } else if (6) << 3 > width { + (6) << 3 + } else { + width + }; + dynalloc_loop_logp = dynalloc_logp; + boost = 0; + while tell + (dynalloc_loop_logp << BITRES) < total_bits + && boost < *cap.as_mut_ptr().offset(i as isize) + { + let mut flag: i32 = 0; + flag = ec_dec_bit_logp(dec, dynalloc_loop_logp as u32); + tell = ec_tell_frac(dec) as i32; + if flag == 0 { + break; + } + boost += quanta; + total_bits -= quanta; + dynalloc_loop_logp = 1; + } + *offsets.as_mut_ptr().offset(i as isize) = boost; + if boost > 0 { + dynalloc_logp = if 2 > dynalloc_logp - 1 { + 2 + } else { + dynalloc_logp - 1 + }; + } + i += 1; + } + let vla_2 = nbEBands as usize; + let mut fine_quant: Vec = ::std::vec::from_elem(0, vla_2); + alloc_trim = if tell + ((6) << BITRES) <= total_bits { + ec_dec_icdf(dec, &trim_icdf, 7) + } else { + 5 + }; + bits = (((len * 8) << BITRES) as u32) + .wrapping_sub(ec_tell_frac(dec)) + .wrapping_sub(1) as i32; + anti_collapse_rsv = if isTransient != 0 && LM >= 2 && bits >= (LM + 2) << BITRES { + (1) << BITRES + } else { + 0 + }; + bits -= anti_collapse_rsv; + let vla_3 = nbEBands as usize; + let mut pulses: Vec = ::std::vec::from_elem(0, vla_3); + let vla_4 = nbEBands as usize; + let mut fine_priority: Vec = ::std::vec::from_elem(0, vla_4); + codedBands = clt_compute_allocation( + mode, + start, + end, + offsets.as_mut_ptr(), + cap.as_mut_ptr(), + alloc_trim, + &mut intensity, + &mut dual_stereo, + bits, + &mut balance, + pulses.as_mut_ptr(), + fine_quant.as_mut_ptr(), + fine_priority.as_mut_ptr(), + C, + LM, + dec, + 0, + 0, + 0, + ); + unquant_fine_energy(mode, start, end, oldBandE, fine_quant.as_mut_ptr(), dec, C); + c = 0; + loop { + memmove( + decode_mem[c as usize] as *mut core::ffi::c_void, + (decode_mem[c as usize]).offset(N as isize) as *const core::ffi::c_void, + ((2048 - N + overlap / 2) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (decode_mem[c as usize]) + .offset_from((decode_mem[c as usize]).offset(N as isize)) + as i64) as u64, + ), + ); + c += 1; + if !(c < CC) { + break; + } + } + let vla_5 = (C * nbEBands) as usize; + let mut collapse_masks: Vec = ::std::vec::from_elem(0, vla_5); + let vla_6 = (C * N) as usize; + let mut X: Vec = ::std::vec::from_elem(0., vla_6); + quant_all_bands( + 0, + mode, + start, + end, + X.as_mut_ptr(), + if C == 2 { + X.as_mut_ptr().offset(N as isize) + } else { + NULL as *mut celt_norm + }, + collapse_masks.as_mut_ptr(), + NULL as *const celt_ener, + pulses.as_mut_ptr(), + shortBlocks, + spread_decision, + dual_stereo, + intensity, + tf_res.as_mut_ptr(), + len * ((8) << BITRES) - anti_collapse_rsv, + balance, + dec, + LM, + codedBands, + &mut (*st).rng, + 0, + (*st).arch, + (*st).disable_inv, + ); + if anti_collapse_rsv > 0 { + anti_collapse_on = ec_dec_bits(dec, 1) as i32; + } + unquant_energy_finalise( + mode, + start, + end, + oldBandE, + fine_quant.as_mut_ptr(), + fine_priority.as_mut_ptr(), + len * 8 - ec_tell(dec), + dec, + C, + ); + if anti_collapse_on != 0 { + anti_collapse( + mode, + X.as_mut_ptr(), + collapse_masks.as_mut_ptr(), + LM, + C, + N, + start, + end, + oldBandE, + oldLogE, + oldLogE2, + pulses.as_mut_ptr(), + (*st).rng, + (*st).arch, + ); + } + if silence != 0 { + i = 0; + while i < C * nbEBands { + *oldBandE.offset(i as isize) = -28.0f32; + i += 1; + } + } + celt_synthesis( + mode, + X.as_mut_ptr(), + out_syn.as_mut_ptr(), + oldBandE, + start, + effEnd, + C, + CC, + isTransient, + LM, + (*st).downsample, + silence, + (*st).arch, + ); + c = 0; + loop { + (*st).postfilter_period = if (*st).postfilter_period > 15 { + (*st).postfilter_period + } else { + 15 + }; + (*st).postfilter_period_old = if (*st).postfilter_period_old > 15 { + (*st).postfilter_period_old + } else { + 15 + }; + comb_filter( + out_syn[c as usize], + out_syn[c as usize], + (*st).postfilter_period_old, + (*st).postfilter_period, + (*mode).shortMdctSize, + (*st).postfilter_gain_old, + (*st).postfilter_gain, + (*st).postfilter_tapset_old, + (*st).postfilter_tapset, + (*mode).window, + overlap, + (*st).arch, + ); + if LM != 0 { + comb_filter( + (out_syn[c as usize]).offset((*mode).shortMdctSize as isize), + (out_syn[c as usize]).offset((*mode).shortMdctSize as isize), + (*st).postfilter_period, + postfilter_pitch, + N - (*mode).shortMdctSize, + (*st).postfilter_gain, + postfilter_gain, + (*st).postfilter_tapset, + postfilter_tapset, + (*mode).window, + overlap, + (*st).arch, + ); + } + c += 1; + if !(c < CC) { + break; + } + } + (*st).postfilter_period_old = (*st).postfilter_period; + (*st).postfilter_gain_old = (*st).postfilter_gain; + (*st).postfilter_tapset_old = (*st).postfilter_tapset; + (*st).postfilter_period = postfilter_pitch; + (*st).postfilter_gain = postfilter_gain; + (*st).postfilter_tapset = postfilter_tapset; + if LM != 0 { + (*st).postfilter_period_old = (*st).postfilter_period; + (*st).postfilter_gain_old = (*st).postfilter_gain; + (*st).postfilter_tapset_old = (*st).postfilter_tapset; + } + if C == 1 { + memcpy( + &mut *oldBandE.offset(nbEBands as isize) as *mut opus_val16 as *mut core::ffi::c_void, + oldBandE as *const core::ffi::c_void, + (nbEBands as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut *oldBandE.offset(nbEBands as isize) as *mut opus_val16) + .offset_from(oldBandE) as i64) as u64, + ), + ); + } + if isTransient == 0 { + let mut max_background_increase: opus_val16 = 0.; + memcpy( + oldLogE2 as *mut core::ffi::c_void, + oldLogE as *const core::ffi::c_void, + ((2 * nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * oldLogE2.offset_from(oldLogE) as i64) as u64), + ); + memcpy( + oldLogE as *mut core::ffi::c_void, + oldBandE as *const core::ffi::c_void, + ((2 * nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * oldLogE.offset_from(oldBandE) as i64) as u64), + ); + if (*st).loss_count < 10 { + max_background_increase = M as f32 * 0.001f32; + } else { + max_background_increase = 1.0f32; + } + i = 0; + while i < 2 * nbEBands { + *backgroundLogE.offset(i as isize) = if *backgroundLogE.offset(i as isize) + + max_background_increase + < *oldBandE.offset(i as isize) + { + *backgroundLogE.offset(i as isize) + max_background_increase + } else { + *oldBandE.offset(i as isize) + }; + i += 1; + } + } else { + i = 0; + while i < 2 * nbEBands { + *oldLogE.offset(i as isize) = + if *oldLogE.offset(i as isize) < *oldBandE.offset(i as isize) { + *oldLogE.offset(i as isize) + } else { + *oldBandE.offset(i as isize) + }; + i += 1; + } + } + c = 0; + loop { + i = 0; + while i < start { + *oldBandE.offset((c * nbEBands + i) as isize) = 0 as opus_val16; + let ref mut fresh0 = *oldLogE2.offset((c * nbEBands + i) as isize); + *fresh0 = -28.0f32; + *oldLogE.offset((c * nbEBands + i) as isize) = *fresh0; + i += 1; + } + i = end; + while i < nbEBands { + *oldBandE.offset((c * nbEBands + i) as isize) = 0 as opus_val16; + let ref mut fresh1 = *oldLogE2.offset((c * nbEBands + i) as isize); + *fresh1 = -28.0f32; + *oldLogE.offset((c * nbEBands + i) as isize) = *fresh1; + i += 1; + } + c += 1; + if !(c < 2) { + break; + } + } + (*st).rng = (*dec).rng; + deemphasis( + out_syn.as_mut_ptr(), + pcm, + N, + CC, + (*st).downsample, + ((*mode).preemph).as_ptr(), + ((*st).preemph_memD).as_mut_ptr(), + accum, + ); + (*st).loss_count = 0; + if ec_tell(dec) > 8 * len { + return OPUS_INTERNAL_ERROR; + } + if ec_get_error(dec) != 0 { + (*st).error = 1; + } + return frame_size / (*st).downsample; +} +pub unsafe fn opus_custom_decoder_ctl_impl( + st: *mut OpusCustomDecoder, + request: i32, + args: VarArgs, +) -> i32 { + let current_block: u64; + let mut ap = args; + match request { + CELT_SET_START_BAND_REQUEST => { + let value: i32 = ap.arg::(); + if value < 0 || value >= (*(*st).mode).nbEBands { + current_block = 7990025728955927862; + } else { + (*st).start = value; + current_block = 3689906465960840878; + } + } + CELT_SET_END_BAND_REQUEST => { + let value_0: i32 = ap.arg::(); + if value_0 < 1 || value_0 > (*(*st).mode).nbEBands { + current_block = 7990025728955927862; + } else { + (*st).end = value_0; + current_block = 3689906465960840878; + } + } + CELT_SET_CHANNELS_REQUEST => { + let value_1: i32 = ap.arg::(); + if value_1 < 1 || value_1 > 2 { + current_block = 7990025728955927862; + } else { + (*st).stream_channels = value_1; + current_block = 3689906465960840878; + } + } + CELT_GET_AND_CLEAR_ERROR_REQUEST => { + let value_2: &mut i32 = ap.arg::<&mut i32>(); + *value_2 = (*st).error; + (*st).error = 0; + current_block = 3689906465960840878; + } + OPUS_GET_LOOKAHEAD_REQUEST => { + let value_3 = ap.arg::<&mut i32>(); + *value_3 = (*st).overlap / (*st).downsample; + current_block = 3689906465960840878; + } + OPUS_RESET_STATE => { + let mut i: i32 = 0; + let mut lpc: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16; + lpc = ((*st)._decode_mem) + .as_mut_ptr() + .offset(((DECODE_BUFFER_SIZE + (*st).overlap) * (*st).channels) as isize) + as *mut opus_val16; + oldBandE = lpc.offset(((*st).channels * LPC_ORDER) as isize); + oldLogE = oldBandE.offset((2 * (*(*st).mode).nbEBands) as isize); + oldLogE2 = oldLogE.offset((2 * (*(*st).mode).nbEBands) as isize); + memset( + &mut (*st).rng as *mut u32 as *mut i8 as *mut core::ffi::c_void, + 0, + ((opus_custom_decoder_get_size((*st).mode, (*st).channels) as i64 + - (&mut (*st).rng as *mut u32 as *mut i8).offset_from(st as *mut i8) as i64) + as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + i = 0; + while i < 2 * (*(*st).mode).nbEBands { + let ref mut fresh2 = *oldLogE2.offset(i as isize); + *fresh2 = -28.0f32; + *oldLogE.offset(i as isize) = *fresh2; + i += 1; + } + (*st).skip_plc = 1; + current_block = 3689906465960840878; + } + OPUS_GET_PITCH_REQUEST => { + let value_4 = ap.arg::<&mut i32>(); + *value_4 = (*st).postfilter_period; + current_block = 3689906465960840878; + } + CELT_GET_MODE_REQUEST => { + let value_5 = ap.arg::<&mut *const OpusCustomMode>(); + *value_5 = (*st).mode; + current_block = 3689906465960840878; + } + CELT_SET_SIGNALLING_REQUEST => { + let value_6: i32 = ap.arg::(); + (*st).signalling = value_6; + current_block = 3689906465960840878; + } + OPUS_GET_FINAL_RANGE_REQUEST => { + let value_7 = ap.arg::<&mut u32>(); + *value_7 = (*st).rng; + current_block = 3689906465960840878; + } + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_8: i32 = ap.arg::(); + if value_8 < 0 || value_8 > 1 { + current_block = 7990025728955927862; + } else { + (*st).disable_inv = value_8; + current_block = 3689906465960840878; + } + } + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_9 = ap.arg::<&mut i32>(); + *value_9 = (*st).disable_inv; + current_block = 3689906465960840878; + } + _ => return OPUS_UNIMPLEMENTED, + } + match current_block { + 3689906465960840878 => return OPUS_OK, + _ => return OPUS_BAD_ARG, + }; +} +#[macro_export] +macro_rules! opus_custom_decoder_ctl { + ($st:expr, $request:expr, $($arg:expr),*) => { + $crate::opus_custom_decoder_ctl_impl($st, $request, $crate::varargs!($($arg),*)) + }; + ($st:expr, $request:expr) => { + opus_custom_decoder_ctl!($st, $request,) + }; + ($st:expr, $request:expr, $($arg:expr),*,) => { + opus_custom_decoder_ctl!($st, $request, $($arg),*) + }; +} diff --git a/vendor/unsafe-libopus/src/celt/celt_encoder.rs b/vendor/unsafe-libopus/src/celt/celt_encoder.rs new file mode 100644 index 00000000..5ff3e234 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/celt_encoder.rs @@ -0,0 +1,3513 @@ +use crate::celt::bands::{ + compute_band_energies, haar1, hysteresis_decision, normalise_bands, quant_all_bands, + spreading_decision, SPREAD_AGGRESSIVE, SPREAD_NONE, SPREAD_NORMAL, +}; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub type celt_sig = f32; + pub type celt_norm = f32; + pub type celt_ener = f32; + pub const CELT_SIG_SCALE: f32 = 32768.0f32; + pub const EPSILON: f32 = 1e-15f32; +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct SILKInfo { + pub signalType: i32, + pub offset: i32, +} + +pub mod stddef_h { + pub const NULL: i32 = 0; +} +pub use self::arch_h::{ + celt_ener, celt_norm, celt_sig, opus_val16, opus_val32, CELT_SIG_SCALE, EPSILON, +}; +pub use self::stddef_h::NULL; +use crate::celt::celt::{ + comb_filter, init_caps, resampling_factor, spread_icdf, tapset_icdf, tf_select_table, trim_icdf, +}; +use crate::celt::celt::{ + CELT_GET_MODE_REQUEST, CELT_SET_ANALYSIS_REQUEST, CELT_SET_CHANNELS_REQUEST, + CELT_SET_END_BAND_REQUEST, CELT_SET_PREDICTION_REQUEST, CELT_SET_SIGNALLING_REQUEST, + CELT_SET_SILK_INFO_REQUEST, CELT_SET_START_BAND_REQUEST, COMBFILTER_MAXPERIOD, + COMBFILTER_MINPERIOD, OPUS_SET_ENERGY_MASK_REQUEST, OPUS_SET_LFE_REQUEST, +}; +use crate::celt::entcode::{ec_get_error, ec_tell, ec_tell_frac, BITRES}; +use crate::celt::entenc::{ + ec_enc, ec_enc_bit_logp, ec_enc_bits, ec_enc_done, ec_enc_icdf, ec_enc_init, ec_enc_shrink, + ec_enc_uint, +}; +use crate::celt::mathops::{celt_exp2, celt_log2, celt_maxabs16, celt_sqrt}; +use crate::celt::mdct::clt_mdct_forward_c; +use crate::celt::modes::{opus_custom_mode_create, OpusCustomMode}; +use crate::celt::pitch::{celt_inner_prod_c, pitch_downsample, pitch_search, remove_doubling}; +use crate::celt::quant_bands::{ + amp2Log2, eMeans, quant_coarse_energy, quant_energy_finalise, quant_fine_energy, +}; +use crate::celt::rate::clt_compute_allocation; +use crate::externs::{memcpy, memmove, memset}; +use crate::opus_custom_encoder_ctl; +use crate::silk::macros::EC_CLZ0; +use crate::src::analysis::AnalysisInfo; +use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_BITRATE_MAX, OPUS_GET_FINAL_RANGE_REQUEST, + OPUS_GET_LSB_DEPTH_REQUEST, OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_INTERNAL_ERROR, + OPUS_OK, OPUS_RESET_STATE, OPUS_SET_BITRATE_REQUEST, OPUS_SET_COMPLEXITY_REQUEST, + OPUS_SET_LSB_DEPTH_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST, + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_SET_VBR_CONSTRAINT_REQUEST, + OPUS_SET_VBR_REQUEST, OPUS_UNIMPLEMENTED, +}; +use crate::varargs::VarArgs; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusCustomEncoder { + pub mode: *const OpusCustomMode, + pub channels: i32, + pub stream_channels: i32, + pub force_intra: i32, + pub clip: i32, + pub disable_pf: i32, + pub complexity: i32, + pub upsample: i32, + pub start: i32, + pub end: i32, + pub bitrate: i32, + pub vbr: i32, + pub signalling: i32, + pub constrained_vbr: i32, + pub loss_rate: i32, + pub lsb_depth: i32, + pub lfe: i32, + pub disable_inv: i32, + pub arch: i32, + pub rng: u32, + pub spread_decision: i32, + pub delayedIntra: opus_val32, + pub tonal_average: i32, + pub lastCodedBands: i32, + pub hf_average: i32, + pub tapset_decision: i32, + pub prefilter_period: i32, + pub prefilter_gain: opus_val16, + pub prefilter_tapset: i32, + pub consec_transient: i32, + pub analysis: AnalysisInfo, + pub silk_info: SILKInfo, + pub preemph_memE: [opus_val32; 2], + pub preemph_memD: [opus_val32; 2], + pub vbr_reservoir: i32, + pub vbr_drift: i32, + pub vbr_offset: i32, + pub vbr_count: i32, + pub overlap_max: opus_val32, + pub stereo_saving: opus_val16, + pub intensity: i32, + pub energy_mask: *mut opus_val16, + pub spec_avg: opus_val16, + pub in_mem: [celt_sig; 1], +} +pub unsafe fn celt_encoder_get_size(channels: i32) -> i32 { + let mode: *const OpusCustomMode = opus_custom_mode_create(48000, 960, NULL as *mut i32); + return opus_custom_encoder_get_size(mode, channels); +} +#[inline] +unsafe fn opus_custom_encoder_get_size(mode: *const OpusCustomMode, channels: i32) -> i32 { + let size: i32 = (::core::mem::size_of::() as u64) + .wrapping_add( + ((channels * (*mode).overlap - 1) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) + .wrapping_add( + ((channels * COMBFILTER_MAXPERIOD) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) + .wrapping_add( + ((4 * channels * (*mode).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as i32; + return size; +} +unsafe fn opus_custom_encoder_init_arch( + st: *mut OpusCustomEncoder, + mode: *const OpusCustomMode, + channels: i32, + arch: i32, +) -> i32 { + if channels < 0 || channels > 2 { + return OPUS_BAD_ARG; + } + if st.is_null() || mode.is_null() { + return OPUS_ALLOC_FAIL; + } + memset( + st as *mut i8 as *mut core::ffi::c_void, + 0, + (opus_custom_encoder_get_size(mode, channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + (*st).mode = mode; + (*st).channels = channels; + (*st).stream_channels = (*st).channels; + (*st).upsample = 1; + (*st).start = 0; + (*st).end = (*(*st).mode).effEBands; + (*st).signalling = 1; + (*st).arch = arch; + (*st).constrained_vbr = 1; + (*st).clip = 1; + (*st).bitrate = OPUS_BITRATE_MAX; + (*st).vbr = 0; + (*st).force_intra = 0; + (*st).complexity = 5; + (*st).lsb_depth = 24; + opus_custom_encoder_ctl!(st, OPUS_RESET_STATE); + return OPUS_OK; +} +pub unsafe fn celt_encoder_init( + st: *mut OpusCustomEncoder, + sampling_rate: i32, + channels: i32, + arch: i32, +) -> i32 { + let mut ret: i32 = 0; + ret = opus_custom_encoder_init_arch( + st, + opus_custom_mode_create(48000, 960, NULL as *mut i32), + channels, + arch, + ); + if ret != OPUS_OK { + return ret; + } + (*st).upsample = resampling_factor(sampling_rate); + return OPUS_OK; +} +unsafe fn transient_analysis( + in_0: *const opus_val32, + len: i32, + C: i32, + tf_estimate: *mut opus_val16, + tf_chan: *mut i32, + allow_weak_transients: i32, + weak_transient: *mut i32, +) -> i32 { + let mut i: i32 = 0; + let mut mem0: opus_val32 = 0.; + let mut mem1: opus_val32 = 0.; + let mut is_transient: i32 = 0; + let mut mask_metric: i32 = 0; + let mut c: i32 = 0; + let mut tf_max: opus_val16 = 0.; + let mut len2: i32 = 0; + let mut forward_decay: opus_val16 = 0.0625f32; + static mut inv_table: [u8; 128] = [ + 255, 255, 156, 110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, 23, 22, 21, 20, 19, 18, + 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, + 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + ]; + let vla = len as usize; + let mut tmp: Vec = ::std::vec::from_elem(0., vla); + *weak_transient = 0; + if allow_weak_transients != 0 { + forward_decay = 0.03125f32; + } + len2 = len / 2; + c = 0; + while c < C { + let mut mean: opus_val32 = 0.; + let mut unmask: i32 = 0; + let mut norm: opus_val32 = 0.; + let mut maxE: opus_val16 = 0.; + mem0 = 0 as opus_val32; + mem1 = 0 as opus_val32; + i = 0; + while i < len { + let mut x: opus_val32 = 0.; + let mut y: opus_val32 = 0.; + x = *in_0.offset((i + c * len) as isize); + y = mem0 + x; + mem0 = mem1 + y - 2 as f32 * x; + mem1 = x - 0.5f32 * y; + *tmp.as_mut_ptr().offset(i as isize) = y; + i += 1; + } + memset( + tmp.as_mut_ptr() as *mut core::ffi::c_void, + 0, + (12_u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + mean = 0 as opus_val32; + mem0 = 0 as opus_val32; + i = 0; + while i < len2 { + let x2: opus_val16 = *tmp.as_mut_ptr().offset((2 * i) as isize) + * *tmp.as_mut_ptr().offset((2 * i) as isize) + + *tmp.as_mut_ptr().offset((2 * i + 1) as isize) + * *tmp.as_mut_ptr().offset((2 * i + 1) as isize); + mean += x2; + *tmp.as_mut_ptr().offset(i as isize) = mem0 + forward_decay * (x2 - mem0); + mem0 = *tmp.as_mut_ptr().offset(i as isize); + i += 1; + } + mem0 = 0 as opus_val32; + maxE = 0 as opus_val16; + i = len2 - 1; + while i >= 0 { + *tmp.as_mut_ptr().offset(i as isize) = + mem0 + 0.125f32 * (*tmp.as_mut_ptr().offset(i as isize) - mem0); + mem0 = *tmp.as_mut_ptr().offset(i as isize); + maxE = if maxE > mem0 { maxE } else { mem0 }; + i -= 1; + } + mean = celt_sqrt((mean * maxE) * 0.5f32 * len2 as f32); + norm = len2 as f32 / (1e-15f32 + mean); + unmask = 0; + assert!(!(*tmp.as_mut_ptr().offset(0)).is_nan()); + assert!(!norm.is_nan()); + i = 12; + while i < len2 - 5 { + let mut id: i32 = 0; + id = (if 0.0 + > (if 127.0 + < (64.0 * norm * (*tmp.as_mut_ptr().offset(i as isize) + 1e-15f32)).floor() + { + 127.0 + } else { + (64.0 * norm * (*tmp.as_mut_ptr().offset(i as isize) + 1e-15f32)).floor() + }) { + 0.0 + } else if 127.0 + < (64.0 * norm * (*tmp.as_mut_ptr().offset(i as isize) + 1e-15f32)).floor() + { + 127.0 + } else { + (64.0 * norm * (*tmp.as_mut_ptr().offset(i as isize) + 1e-15f32)).floor() + }) as i32; + unmask += inv_table[id as usize] as i32; + i += 4; + } + unmask = 64 * unmask * 4 / (6 * (len2 - 17)); + if unmask > mask_metric { + *tf_chan = c; + mask_metric = unmask; + } + c += 1; + } + is_transient = (mask_metric > 200) as i32; + if allow_weak_transients != 0 && is_transient != 0 && mask_metric < 600 { + is_transient = 0; + *weak_transient = 1; + } + tf_max = if 0 as f32 > celt_sqrt((27 * mask_metric) as f32) - 42 as f32 { + 0 as f32 + } else { + celt_sqrt((27 * mask_metric) as f32) - 42 as f32 + }; + *tf_estimate = (if 0 as f64 + > (0.0069f64 as opus_val32 + * (if (163 as f32) < tf_max { + 163 as f32 + } else { + tf_max + })) as f64 + - 0.139f64 + { + 0 as f64 + } else { + (0.0069f64 as opus_val32 + * (if (163 as f32) < tf_max { + 163 as f32 + } else { + tf_max + })) as f64 + - 0.139f64 + }) + // here, a 64-bit sqrt __should__ be used + .sqrt() as f32; + return is_transient; +} +unsafe fn patch_transient_decision( + newE: *mut opus_val16, + oldE: *mut opus_val16, + nbEBands: i32, + start: i32, + end: i32, + C: i32, +) -> i32 { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut mean_diff: opus_val32 = 0 as opus_val32; + let mut spread_old: [opus_val16; 26] = [0.; 26]; + if C == 1 { + spread_old[start as usize] = *oldE.offset(start as isize); + i = start + 1; + while i < end { + spread_old[i as usize] = + if spread_old[(i - 1) as usize] - 1.0f32 > *oldE.offset(i as isize) { + spread_old[(i - 1) as usize] - 1.0f32 + } else { + *oldE.offset(i as isize) + }; + i += 1; + } + } else { + spread_old[start as usize] = + if *oldE.offset(start as isize) > *oldE.offset((start + nbEBands) as isize) { + *oldE.offset(start as isize) + } else { + *oldE.offset((start + nbEBands) as isize) + }; + i = start + 1; + while i < end { + spread_old[i as usize] = if spread_old[(i - 1) as usize] - 1.0f32 + > (if *oldE.offset(i as isize) > *oldE.offset((i + nbEBands) as isize) { + *oldE.offset(i as isize) + } else { + *oldE.offset((i + nbEBands) as isize) + }) { + spread_old[(i - 1) as usize] - 1.0f32 + } else if *oldE.offset(i as isize) > *oldE.offset((i + nbEBands) as isize) { + *oldE.offset(i as isize) + } else { + *oldE.offset((i + nbEBands) as isize) + }; + i += 1; + } + } + i = end - 2; + while i >= start { + spread_old[i as usize] = if spread_old[i as usize] > spread_old[(i + 1) as usize] - 1.0f32 { + spread_old[i as usize] + } else { + spread_old[(i + 1) as usize] - 1.0f32 + }; + i -= 1; + } + c = 0; + loop { + i = if 2 > start { 2 } else { start }; + while i < end - 1 { + let mut x1: opus_val16 = 0.; + let mut x2: opus_val16 = 0.; + x1 = if 0 as f32 > *newE.offset((i + c * nbEBands) as isize) { + 0 as f32 + } else { + *newE.offset((i + c * nbEBands) as isize) + }; + x2 = if 0 as f32 > spread_old[i as usize] { + 0 as f32 + } else { + spread_old[i as usize] + }; + mean_diff = mean_diff + + (if 0 as f32 > x1 - x2 { + 0 as f32 + } else { + x1 - x2 + }); + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + mean_diff = mean_diff / (C * (end - 1 - (if 2 > start { 2 } else { start }))) as opus_val32; + return (mean_diff > 1.0f32) as i32; +} +unsafe fn compute_mdcts( + mode: *const OpusCustomMode, + shortBlocks: i32, + in_0: *mut celt_sig, + out: *mut celt_sig, + C: i32, + CC: i32, + LM: i32, + upsample: i32, + arch: i32, +) { + let overlap: i32 = (*mode).overlap; + let mut N: i32 = 0; + let mut B: i32 = 0; + let mut shift: i32 = 0; + let mut i: i32 = 0; + let mut b: i32 = 0; + let mut c: i32 = 0; + if shortBlocks != 0 { + B = shortBlocks; + N = (*mode).shortMdctSize; + shift = (*mode).maxLM; + } else { + B = 1; + N = (*mode).shortMdctSize << LM; + shift = (*mode).maxLM - LM; + } + c = 0; + loop { + b = 0; + while b < B { + clt_mdct_forward_c( + &(*mode).mdct, + in_0.offset((c * (B * N + overlap)) as isize) + .offset((b * N) as isize), + &mut *out.offset((b + c * N * B) as isize), + (*mode).window, + overlap, + shift, + B, + arch, + ); + b += 1; + } + c += 1; + if !(c < CC) { + break; + } + } + if CC == 2 && C == 1 { + i = 0; + while i < B * N { + *out.offset(i as isize) = + 0.5f32 * *out.offset(i as isize) + 0.5f32 * *out.offset((B * N + i) as isize); + i += 1; + } + } + if upsample != 1 { + c = 0; + loop { + let bound: i32 = B * N / upsample; + i = 0; + while i < bound { + let ref mut fresh0 = *out.offset((c * B * N + i) as isize); + *fresh0 *= upsample as f32; + i += 1; + } + memset( + &mut *out.offset((c * B * N + bound) as isize) as *mut celt_sig + as *mut core::ffi::c_void, + 0, + ((B * N - bound) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + c += 1; + if !(c < C) { + break; + } + } + } +} +pub unsafe fn celt_preemphasis( + pcmp: *const opus_val16, + inp: *mut celt_sig, + N: i32, + CC: i32, + upsample: i32, + coef: *const opus_val16, + mem: *mut celt_sig, + clip: i32, +) { + let mut i: i32 = 0; + let mut coef0: opus_val16 = 0.; + let mut m: celt_sig = 0.; + let mut Nu: i32 = 0; + coef0 = *coef.offset(0 as isize); + m = *mem; + if *coef.offset(1 as isize) == 0 as f32 && upsample == 1 && clip == 0 { + i = 0; + while i < N { + let mut x: opus_val16 = 0.; + x = *pcmp.offset((CC * i) as isize) * CELT_SIG_SCALE; + *inp.offset(i as isize) = x - m; + m = coef0 * x; + i += 1; + } + *mem = m; + return; + } + Nu = N / upsample; + if upsample != 1 { + memset( + inp as *mut core::ffi::c_void, + 0, + (N as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } + i = 0; + while i < Nu { + *inp.offset((i * upsample) as isize) = *pcmp.offset((CC * i) as isize) * CELT_SIG_SCALE; + i += 1; + } + if clip != 0 { + i = 0; + while i < Nu { + *inp.offset((i * upsample) as isize) = if -65536.0f32 + > (if 65536.0f32 < *inp.offset((i * upsample) as isize) { + 65536.0f32 + } else { + *inp.offset((i * upsample) as isize) + }) { + -65536.0f32 + } else if 65536.0f32 < *inp.offset((i * upsample) as isize) { + 65536.0f32 + } else { + *inp.offset((i * upsample) as isize) + }; + i += 1; + } + } + i = 0; + while i < N { + let mut x_0: opus_val16 = 0.; + x_0 = *inp.offset(i as isize); + *inp.offset(i as isize) = x_0 - m; + m = coef0 * x_0; + i += 1; + } + *mem = m; +} +unsafe fn l1_metric(tmp: *const celt_norm, N: i32, LM: i32, bias: opus_val16) -> opus_val32 { + let mut i: i32 = 0; + let mut L1: opus_val32 = 0.; + L1 = 0 as opus_val32; + i = 0; + while i < N { + L1 += (*tmp.offset(i as isize)).abs(); + i += 1; + } + L1 = L1 + LM as f32 * bias * L1; + return L1; +} +unsafe fn tf_analysis( + m: *const OpusCustomMode, + len: i32, + isTransient: i32, + tf_res: *mut i32, + lambda: i32, + X: *mut celt_norm, + N0: i32, + LM: i32, + tf_estimate: opus_val16, + tf_chan: i32, + importance: *mut i32, +) -> i32 { + let mut i: i32 = 0; + let mut cost0: i32 = 0; + let mut cost1: i32 = 0; + let mut sel: i32 = 0; + let mut selcost: [i32; 2] = [0; 2]; + let mut tf_select: i32 = 0; + let mut bias: opus_val16 = 0.; + bias = 0.04f32 + * (if -0.25f32 > 0.5f32 - tf_estimate { + -0.25f32 + } else { + 0.5f32 - tf_estimate + }); + let vla = len as usize; + let mut metric: Vec = ::std::vec::from_elem(0, vla); + let vla_0 = ((*((*m).eBands).offset(len as isize) as i32 + - *((*m).eBands).offset((len - 1) as isize) as i32) + << LM) as usize; + let mut tmp: Vec = ::std::vec::from_elem(0., vla_0); + let vla_1 = ((*((*m).eBands).offset(len as isize) as i32 + - *((*m).eBands).offset((len - 1) as isize) as i32) + << LM) as usize; + let mut tmp_1: Vec = ::std::vec::from_elem(0., vla_1); + let vla_2 = len as usize; + let mut path0: Vec = ::std::vec::from_elem(0, vla_2); + let vla_3 = len as usize; + let mut path1: Vec = ::std::vec::from_elem(0, vla_3); + i = 0; + while i < len { + let mut k: i32 = 0; + let mut N: i32 = 0; + let mut narrow: i32 = 0; + let mut L1: opus_val32 = 0.; + let mut best_L1: opus_val32 = 0.; + let mut best_level: i32 = 0; + N = (*((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32) + << LM; + narrow = (*((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32 + == 1) as i32; + memcpy( + tmp.as_mut_ptr() as *mut core::ffi::c_void, + &mut *X.offset( + (tf_chan * N0 + ((*((*m).eBands).offset(i as isize) as i32) << LM)) as isize, + ) as *mut celt_norm as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * tmp.as_mut_ptr().offset_from(&mut *X.offset( + (tf_chan * N0 + ((*((*m).eBands).offset(i as isize) as i32) << LM)) + as isize, + )) as i64) as u64, + ), + ); + L1 = l1_metric( + tmp.as_mut_ptr(), + N, + if isTransient != 0 { LM } else { 0 }, + bias, + ); + best_L1 = L1; + if isTransient != 0 && narrow == 0 { + memcpy( + tmp_1.as_mut_ptr() as *mut core::ffi::c_void, + tmp.as_mut_ptr() as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * tmp_1.as_mut_ptr().offset_from(tmp.as_mut_ptr()) as i64) as u64, + ), + ); + haar1(tmp_1.as_mut_ptr(), N >> LM, (1) << LM); + L1 = l1_metric(tmp_1.as_mut_ptr(), N, LM + 1, bias); + if L1 < best_L1 { + best_L1 = L1; + best_level = -1; + } + } + k = 0; + while k < LM + !(isTransient != 0 || narrow != 0) as i32 { + let mut B: i32 = 0; + if isTransient != 0 { + B = LM - k - 1; + } else { + B = k + 1; + } + haar1(tmp.as_mut_ptr(), N >> k, (1) << k); + L1 = l1_metric(tmp.as_mut_ptr(), N, B, bias); + if L1 < best_L1 { + best_L1 = L1; + best_level = k + 1; + } + k += 1; + } + if isTransient != 0 { + *metric.as_mut_ptr().offset(i as isize) = 2 * best_level; + } else { + *metric.as_mut_ptr().offset(i as isize) = -(2) * best_level; + } + if narrow != 0 + && (*metric.as_mut_ptr().offset(i as isize) == 0 + || *metric.as_mut_ptr().offset(i as isize) == -(2) * LM) + { + *metric.as_mut_ptr().offset(i as isize) -= 1; + } + i += 1; + } + tf_select = 0; + sel = 0; + while sel < 2 { + cost0 = *importance.offset(0 as isize) + * (*metric.as_mut_ptr().offset(0 as isize) + - 2 * tf_select_table[LM as usize][(4 * isTransient + 2 * sel + 0) as usize] + as i32) + .abs(); + cost1 = *importance.offset(0 as isize) + * (*metric.as_mut_ptr().offset(0 as isize) + - 2 * tf_select_table[LM as usize][(4 * isTransient + 2 * sel + 1) as usize] + as i32) + .abs() + + (if isTransient != 0 { 0 } else { lambda }); + i = 1; + while i < len { + let mut curr0: i32 = 0; + let mut curr1: i32 = 0; + curr0 = if cost0 < cost1 + lambda { + cost0 + } else { + cost1 + lambda + }; + curr1 = if cost0 + lambda < cost1 { + cost0 + lambda + } else { + cost1 + }; + cost0 = curr0 + + *importance.offset(i as isize) + * (*metric.as_mut_ptr().offset(i as isize) + - 2 * tf_select_table[LM as usize][(4 * isTransient + 2 * sel + 0) as usize] + as i32) + .abs(); + cost1 = curr1 + + *importance.offset(i as isize) + * (*metric.as_mut_ptr().offset(i as isize) + - 2 * tf_select_table[LM as usize][(4 * isTransient + 2 * sel + 1) as usize] + as i32) + .abs(); + i += 1; + } + cost0 = if cost0 < cost1 { cost0 } else { cost1 }; + selcost[sel as usize] = cost0; + sel += 1; + } + if selcost[1 as usize] < selcost[0 as usize] && isTransient != 0 { + tf_select = 1; + } + cost0 = *importance.offset(0 as isize) + * (*metric.as_mut_ptr().offset(0 as isize) + - 2 * tf_select_table[LM as usize][(4 * isTransient + 2 * tf_select + 0) as usize] + as i32) + .abs(); + cost1 = *importance.offset(0 as isize) + * (*metric.as_mut_ptr().offset(0 as isize) + - 2 * tf_select_table[LM as usize][(4 * isTransient + 2 * tf_select + 1) as usize] + as i32) + .abs() + + (if isTransient != 0 { 0 } else { lambda }); + i = 1; + while i < len { + let mut curr0_0: i32 = 0; + let mut curr1_0: i32 = 0; + let mut from0: i32 = 0; + let mut from1: i32 = 0; + from0 = cost0; + from1 = cost1 + lambda; + if from0 < from1 { + curr0_0 = from0; + *path0.as_mut_ptr().offset(i as isize) = 0; + } else { + curr0_0 = from1; + *path0.as_mut_ptr().offset(i as isize) = 1; + } + from0 = cost0 + lambda; + from1 = cost1; + if from0 < from1 { + curr1_0 = from0; + *path1.as_mut_ptr().offset(i as isize) = 0; + } else { + curr1_0 = from1; + *path1.as_mut_ptr().offset(i as isize) = 1; + } + cost0 = curr0_0 + + *importance.offset(i as isize) + * (*metric.as_mut_ptr().offset(i as isize) + - 2 * tf_select_table[LM as usize] + [(4 * isTransient + 2 * tf_select + 0) as usize] + as i32) + .abs(); + cost1 = curr1_0 + + *importance.offset(i as isize) + * (*metric.as_mut_ptr().offset(i as isize) + - 2 * tf_select_table[LM as usize] + [(4 * isTransient + 2 * tf_select + 1) as usize] + as i32) + .abs(); + i += 1; + } + *tf_res.offset((len - 1) as isize) = if cost0 < cost1 { 0 } else { 1 }; + i = len - 2; + while i >= 0 { + if *tf_res.offset((i + 1) as isize) == 1 { + *tf_res.offset(i as isize) = *path1.as_mut_ptr().offset((i + 1) as isize); + } else { + *tf_res.offset(i as isize) = *path0.as_mut_ptr().offset((i + 1) as isize); + } + i -= 1; + } + return tf_select; +} +unsafe fn tf_encode( + start: i32, + end: i32, + isTransient: i32, + tf_res: *mut i32, + LM: i32, + mut tf_select: i32, + enc: &mut ec_enc, +) { + let mut curr: i32 = 0; + let mut i: i32 = 0; + let mut tf_select_rsv: i32 = 0; + let mut tf_changed: i32 = 0; + let mut logp: i32 = 0; + let mut budget: u32 = 0; + let mut tell: u32 = 0; + budget = ((*enc).storage).wrapping_mul(8); + tell = ec_tell(enc) as u32; + logp = if isTransient != 0 { 2 } else { 4 }; + tf_select_rsv = (LM > 0 && tell.wrapping_add(logp as u32).wrapping_add(1) <= budget) as i32; + budget = (budget as u32).wrapping_sub(tf_select_rsv as u32) as u32 as u32; + tf_changed = 0; + curr = tf_changed; + i = start; + while i < end { + if tell.wrapping_add(logp as u32) <= budget { + ec_enc_bit_logp(enc, *tf_res.offset(i as isize) ^ curr, logp as u32); + tell = ec_tell(enc) as u32; + curr = *tf_res.offset(i as isize); + tf_changed |= curr; + } else { + *tf_res.offset(i as isize) = curr; + } + logp = if isTransient != 0 { 4 } else { 5 }; + i += 1; + } + if tf_select_rsv != 0 + && tf_select_table[LM as usize][(4 * isTransient + 0 + tf_changed) as usize] as i32 + != tf_select_table[LM as usize][(4 * isTransient + 2 + tf_changed) as usize] as i32 + { + ec_enc_bit_logp(enc, tf_select, 1); + } else { + tf_select = 0; + } + i = start; + while i < end { + *tf_res.offset(i as isize) = tf_select_table[LM as usize] + [(4 * isTransient + 2 * tf_select + *tf_res.offset(i as isize)) as usize] + as i32; + i += 1; + } +} +unsafe fn alloc_trim_analysis( + m: *const OpusCustomMode, + X: *const celt_norm, + bandLogE: *const opus_val16, + end: i32, + LM: i32, + C: i32, + N0: i32, + analysis: *mut AnalysisInfo, + stereo_saving: *mut opus_val16, + tf_estimate: opus_val16, + intensity: i32, + surround_trim: opus_val16, + equiv_rate: i32, + _arch: i32, +) -> i32 { + let mut i: i32 = 0; + let mut diff: opus_val32 = 0 as opus_val32; + let mut c: i32 = 0; + let mut trim_index: i32 = 0; + let mut trim: opus_val16 = 5.0f32; + let mut logXC: opus_val16 = 0.; + let mut logXC2: opus_val16 = 0.; + if equiv_rate < 64000 { + trim = 4.0f32; + } else if equiv_rate < 80000 { + let frac: i32 = equiv_rate - 64000 >> 10; + trim = 4.0f32 + 1.0f32 / 16.0f32 * frac as f32; + } + if C == 2 { + let mut sum: opus_val16 = 0 as opus_val16; + let mut minXC: opus_val16 = 0.; + i = 0; + while i < 8 { + let mut partial: opus_val32 = 0.; + partial = celt_inner_prod_c( + &*X.offset(((*((*m).eBands).offset(i as isize) as i32) << LM) as isize), + &*X.offset((N0 + ((*((*m).eBands).offset(i as isize) as i32) << LM)) as isize), + (*((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32) + << LM, + ); + sum = sum + partial; + i += 1; + } + sum = 1.0f32 / 8 as f32 * sum; + sum = if 1.0f32 < (sum).abs() { + 1.0f32 + } else { + (sum).abs() + }; + minXC = sum; + i = 8; + while i < intensity { + let mut partial_0: opus_val32 = 0.; + partial_0 = celt_inner_prod_c( + &*X.offset(((*((*m).eBands).offset(i as isize) as i32) << LM) as isize), + &*X.offset((N0 + ((*((*m).eBands).offset(i as isize) as i32) << LM)) as isize), + (*((*m).eBands).offset((i + 1) as isize) as i32 + - *((*m).eBands).offset(i as isize) as i32) + << LM, + ); + minXC = if minXC < (partial_0).abs() { + minXC + } else { + (partial_0).abs() + }; + i += 1; + } + minXC = if 1.0f32 < (minXC).abs() { + 1.0f32 + } else { + (minXC).abs() + }; + logXC = celt_log2(1.001f32 - sum * sum); + logXC2 = if 0.5f32 * logXC > celt_log2(1.001f32 - minXC * minXC) { + 0.5f32 * logXC + } else { + celt_log2(1.001f32 - minXC * minXC) + }; + trim += if -4.0f32 > 0.75f32 * logXC { + -4.0f32 + } else { + 0.75f32 * logXC + }; + *stereo_saving = if *stereo_saving + 0.25f32 < -(0.5f32 * logXC2) { + *stereo_saving + 0.25f32 + } else { + -(0.5f32 * logXC2) + }; + } + c = 0; + loop { + i = 0; + while i < end - 1 { + diff += *bandLogE.offset((i + c * (*m).nbEBands) as isize) * (2 + 2 * i - end) as f32; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + diff /= (C * (end - 1)) as f32; + trim -= if -2.0f32 + > (if 2.0f32 < (diff + 1.0f32) / 6 as f32 { + 2.0f32 + } else { + (diff + 1.0f32) / 6 as f32 + }) { + -2.0f32 + } else if 2.0f32 < (diff + 1.0f32) / 6 as f32 { + 2.0f32 + } else { + (diff + 1.0f32) / 6 as f32 + }; + trim -= surround_trim; + trim -= 2 as f32 * tf_estimate; + if (*analysis).valid != 0 { + trim -= if -2.0f32 + > (if 2.0f32 < 2.0f32 * ((*analysis).tonality_slope + 0.05f32) { + 2.0f32 + } else { + 2.0f32 * ((*analysis).tonality_slope + 0.05f32) + }) { + -2.0f32 + } else if 2.0f32 < 2.0f32 * ((*analysis).tonality_slope + 0.05f32) { + 2.0f32 + } else { + 2.0f32 * ((*analysis).tonality_slope + 0.05f32) + }; + } + trim_index = (0.5f32 + trim).floor() as i32; + trim_index = if 0 > (if (10) < trim_index { 10 } else { trim_index }) { + 0 + } else if (10) < trim_index { + 10 + } else { + trim_index + }; + return trim_index; +} +unsafe fn stereo_analysis(m: *const OpusCustomMode, X: *const celt_norm, LM: i32, N0: i32) -> i32 { + let mut i: i32 = 0; + let mut thetas: i32 = 0; + let mut sumLR: opus_val32 = EPSILON; + let mut sumMS: opus_val32 = EPSILON; + i = 0; + while i < 13 { + let mut j: i32 = 0; + j = (*((*m).eBands).offset(i as isize) as i32) << LM; + while j < (*((*m).eBands).offset((i + 1) as isize) as i32) << LM { + let mut L: opus_val32 = 0.; + let mut R: opus_val32 = 0.; + let mut M: opus_val32 = 0.; + let mut S: opus_val32 = 0.; + L = *X.offset(j as isize); + R = *X.offset((N0 + j) as isize); + M = L + R; + S = L - R; + sumLR = sumLR + ((L).abs() + (R).abs()); + sumMS = sumMS + ((M).abs() + (S).abs()); + j += 1; + } + i += 1; + } + sumMS = 0.707107f32 * sumMS; + thetas = 13; + if LM <= 1 { + thetas -= 8; + } + return ((((*((*m).eBands).offset(13 as isize) as i32) << LM + 1) + thetas) as f32 * sumMS + > ((*((*m).eBands).offset(13 as isize) as i32) << LM + 1) as f32 * sumLR) + as i32; +} +unsafe fn median_of_5(x: *const opus_val16) -> opus_val16 { + let mut t0: opus_val16 = 0.; + let mut t1: opus_val16 = 0.; + let mut t2: opus_val16 = 0.; + let mut t3: opus_val16 = 0.; + let mut t4: opus_val16 = 0.; + t2 = *x.offset(2 as isize); + if *x.offset(0 as isize) > *x.offset(1 as isize) { + t0 = *x.offset(1 as isize); + t1 = *x.offset(0 as isize); + } else { + t0 = *x.offset(0 as isize); + t1 = *x.offset(1 as isize); + } + if *x.offset(3 as isize) > *x.offset(4 as isize) { + t3 = *x.offset(4 as isize); + t4 = *x.offset(3 as isize); + } else { + t3 = *x.offset(3 as isize); + t4 = *x.offset(4 as isize); + } + if t0 > t3 { + let tmp: opus_val16 = t0; + t0 = t3; + t3 = tmp; + let tmp_0: opus_val16 = t1; + t1 = t4; + t4 = tmp_0; + } + if t2 > t1 { + if t1 < t3 { + return if t2 < t3 { t2 } else { t3 }; + } else { + return if t4 < t1 { t4 } else { t1 }; + } + } else if t2 < t3 { + return if t1 < t3 { t1 } else { t3 }; + } else { + return if t2 < t4 { t2 } else { t4 }; + }; +} +unsafe fn median_of_3(x: *const opus_val16) -> opus_val16 { + let mut t0: opus_val16 = 0.; + let mut t1: opus_val16 = 0.; + let mut t2: opus_val16 = 0.; + if *x.offset(0 as isize) > *x.offset(1 as isize) { + t0 = *x.offset(1 as isize); + t1 = *x.offset(0 as isize); + } else { + t0 = *x.offset(0 as isize); + t1 = *x.offset(1 as isize); + } + t2 = *x.offset(2 as isize); + if t1 < t2 { + return t1; + } else if t0 < t2 { + return t2; + } else { + return t0; + }; +} +unsafe fn dynalloc_analysis( + bandLogE: *const opus_val16, + bandLogE2: *const opus_val16, + nbEBands: i32, + start: i32, + end: i32, + C: i32, + offsets: *mut i32, + lsb_depth: i32, + logN: *const i16, + isTransient: i32, + vbr: i32, + constrained_vbr: i32, + eBands: *const i16, + LM: i32, + effectiveBytes: i32, + tot_boost_: *mut i32, + lfe: i32, + surround_dynalloc: *mut opus_val16, + analysis: *mut AnalysisInfo, + importance: *mut i32, + spread_weight: *mut i32, +) -> opus_val16 { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut tot_boost: i32 = 0; + let mut maxDepth: opus_val16 = 0.; + let vla = (C * nbEBands) as usize; + let mut follower: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = (C * nbEBands) as usize; + let mut noise_floor: Vec = ::std::vec::from_elem(0., vla_0); + memset( + offsets as *mut core::ffi::c_void, + 0, + (nbEBands as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + maxDepth = -31.9f32; + i = 0; + while i < end { + *noise_floor.as_mut_ptr().offset(i as isize) = + 0.0625f32 * *logN.offset(i as isize) as opus_val32 + 0.5f32 + (9 - lsb_depth) as f32 + - eMeans[i as usize] + + 0.0062f64 as opus_val32 * ((i + 5) * (i + 5)) as opus_val32; + i += 1; + } + c = 0; + loop { + i = 0; + while i < end { + maxDepth = if maxDepth + > *bandLogE.offset((c * nbEBands + i) as isize) + - *noise_floor.as_mut_ptr().offset(i as isize) + { + maxDepth + } else { + *bandLogE.offset((c * nbEBands + i) as isize) + - *noise_floor.as_mut_ptr().offset(i as isize) + }; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + let vla_1 = nbEBands as usize; + let mut mask: Vec = ::std::vec::from_elem(0., vla_1); + let vla_2 = nbEBands as usize; + let mut sig: Vec = ::std::vec::from_elem(0., vla_2); + i = 0; + while i < end { + *mask.as_mut_ptr().offset(i as isize) = + *bandLogE.offset(i as isize) - *noise_floor.as_mut_ptr().offset(i as isize); + i += 1; + } + if C == 2 { + i = 0; + while i < end { + *mask.as_mut_ptr().offset(i as isize) = if *mask.as_mut_ptr().offset(i as isize) + > *bandLogE.offset((nbEBands + i) as isize) + - *noise_floor.as_mut_ptr().offset(i as isize) + { + *mask.as_mut_ptr().offset(i as isize) + } else { + *bandLogE.offset((nbEBands + i) as isize) + - *noise_floor.as_mut_ptr().offset(i as isize) + }; + i += 1; + } + } + memcpy( + sig.as_mut_ptr() as *mut core::ffi::c_void, + mask.as_mut_ptr() as *const core::ffi::c_void, + (end as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * sig.as_mut_ptr().offset_from(mask.as_mut_ptr()) as i64) as u64), + ); + i = 1; + while i < end { + *mask.as_mut_ptr().offset(i as isize) = if *mask.as_mut_ptr().offset(i as isize) + > *mask.as_mut_ptr().offset((i - 1) as isize) - 2.0f32 + { + *mask.as_mut_ptr().offset(i as isize) + } else { + *mask.as_mut_ptr().offset((i - 1) as isize) - 2.0f32 + }; + i += 1; + } + i = end - 2; + while i >= 0 { + *mask.as_mut_ptr().offset(i as isize) = if *mask.as_mut_ptr().offset(i as isize) + > *mask.as_mut_ptr().offset((i + 1) as isize) - 3.0f32 + { + *mask.as_mut_ptr().offset(i as isize) + } else { + *mask.as_mut_ptr().offset((i + 1) as isize) - 3.0f32 + }; + i -= 1; + } + i = 0; + while i < end { + let smr: opus_val16 = *sig.as_mut_ptr().offset(i as isize) + - (if (if 0 as f32 > maxDepth - 12.0f32 { + 0 as f32 + } else { + maxDepth - 12.0f32 + }) > *mask.as_mut_ptr().offset(i as isize) + { + if 0 as f32 > maxDepth - 12.0f32 { + 0 as f32 + } else { + maxDepth - 12.0f32 + } + } else { + *mask.as_mut_ptr().offset(i as isize) + }); + let shift: i32 = if (5) + < (if 0 > -((0.5f32 + smr).floor() as i32) { + 0 + } else { + -((0.5f32 + smr).floor() as i32) + }) { + 5 + } else if 0 > -((0.5f32 + smr).floor() as i32) { + 0 + } else { + -((0.5f32 + smr).floor() as i32) + }; + *spread_weight.offset(i as isize) = 32 >> shift; + i += 1; + } + if effectiveBytes > 50 && LM >= 1 && lfe == 0 { + let mut last: i32 = 0; + c = 0; + loop { + let mut offset: opus_val16 = 0.; + let mut tmp: opus_val16 = 0.; + let mut f: *mut opus_val16 = 0 as *mut opus_val16; + f = &mut *follower.as_mut_ptr().offset((c * nbEBands) as isize) as *mut opus_val16; + *f.offset(0 as isize) = *bandLogE2.offset((c * nbEBands) as isize); + i = 1; + while i < end { + if *bandLogE2.offset((c * nbEBands + i) as isize) + > *bandLogE2.offset((c * nbEBands + i - 1) as isize) + 0.5f32 + { + last = i; + } + *f.offset(i as isize) = if *f.offset((i - 1) as isize) + 1.5f32 + < *bandLogE2.offset((c * nbEBands + i) as isize) + { + *f.offset((i - 1) as isize) + 1.5f32 + } else { + *bandLogE2.offset((c * nbEBands + i) as isize) + }; + i += 1; + } + i = last - 1; + while i >= 0 { + *f.offset(i as isize) = if *f.offset(i as isize) + < (if *f.offset((i + 1) as isize) + 2.0f32 + < *bandLogE2.offset((c * nbEBands + i) as isize) + { + *f.offset((i + 1) as isize) + 2.0f32 + } else { + *bandLogE2.offset((c * nbEBands + i) as isize) + }) { + *f.offset(i as isize) + } else if *f.offset((i + 1) as isize) + 2.0f32 + < *bandLogE2.offset((c * nbEBands + i) as isize) + { + *f.offset((i + 1) as isize) + 2.0f32 + } else { + *bandLogE2.offset((c * nbEBands + i) as isize) + }; + i -= 1; + } + offset = 1.0f32; + i = 2; + while i < end - 2 { + *f.offset(i as isize) = if *f.offset(i as isize) + > median_of_5(&*bandLogE2.offset((c * nbEBands + i - 2) as isize)) - offset + { + *f.offset(i as isize) + } else { + median_of_5(&*bandLogE2.offset((c * nbEBands + i - 2) as isize)) - offset + }; + i += 1; + } + tmp = median_of_3(&*bandLogE2.offset((c * nbEBands) as isize)) - offset; + *f.offset(0 as isize) = if *f.offset(0 as isize) > tmp { + *f.offset(0 as isize) + } else { + tmp + }; + *f.offset(1 as isize) = if *f.offset(1 as isize) > tmp { + *f.offset(1 as isize) + } else { + tmp + }; + tmp = median_of_3(&*bandLogE2.offset((c * nbEBands + end - 3) as isize)) - offset; + *f.offset((end - 2) as isize) = if *f.offset((end - 2) as isize) > tmp { + *f.offset((end - 2) as isize) + } else { + tmp + }; + *f.offset((end - 1) as isize) = if *f.offset((end - 1) as isize) > tmp { + *f.offset((end - 1) as isize) + } else { + tmp + }; + i = 0; + while i < end { + *f.offset(i as isize) = + if *f.offset(i as isize) > *noise_floor.as_mut_ptr().offset(i as isize) { + *f.offset(i as isize) + } else { + *noise_floor.as_mut_ptr().offset(i as isize) + }; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + if C == 2 { + i = start; + while i < end { + *follower.as_mut_ptr().offset((nbEBands + i) as isize) = + if *follower.as_mut_ptr().offset((nbEBands + i) as isize) + > *follower.as_mut_ptr().offset(i as isize) - 4.0f32 + { + *follower.as_mut_ptr().offset((nbEBands + i) as isize) + } else { + *follower.as_mut_ptr().offset(i as isize) - 4.0f32 + }; + *follower.as_mut_ptr().offset(i as isize) = + if *follower.as_mut_ptr().offset(i as isize) + > *follower.as_mut_ptr().offset((nbEBands + i) as isize) - 4.0f32 + { + *follower.as_mut_ptr().offset(i as isize) + } else { + *follower.as_mut_ptr().offset((nbEBands + i) as isize) - 4.0f32 + }; + *follower.as_mut_ptr().offset(i as isize) = 0.5f32 + * ((if 0 as f32 + > *bandLogE.offset(i as isize) - *follower.as_mut_ptr().offset(i as isize) + { + 0 as f32 + } else { + *bandLogE.offset(i as isize) - *follower.as_mut_ptr().offset(i as isize) + }) + (if 0 as f32 + > *bandLogE.offset((nbEBands + i) as isize) + - *follower.as_mut_ptr().offset((nbEBands + i) as isize) + { + 0 as f32 + } else { + *bandLogE.offset((nbEBands + i) as isize) + - *follower.as_mut_ptr().offset((nbEBands + i) as isize) + })); + i += 1; + } + } else { + i = start; + while i < end { + *follower.as_mut_ptr().offset(i as isize) = if 0 as f32 + > *bandLogE.offset(i as isize) - *follower.as_mut_ptr().offset(i as isize) + { + 0 as f32 + } else { + *bandLogE.offset(i as isize) - *follower.as_mut_ptr().offset(i as isize) + }; + i += 1; + } + } + i = start; + while i < end { + *follower.as_mut_ptr().offset(i as isize) = if *follower.as_mut_ptr().offset(i as isize) + > *surround_dynalloc.offset(i as isize) + { + *follower.as_mut_ptr().offset(i as isize) + } else { + *surround_dynalloc.offset(i as isize) + }; + i += 1; + } + i = start; + while i < end { + *importance.offset(i as isize) = (0.5f32 + + 13.0 + * celt_exp2(if *follower.as_mut_ptr().offset(i as isize) < 4.0f32 { + *follower.as_mut_ptr().offset(i as isize) + } else { + 4.0f32 + })) + .floor() as i32; + i += 1; + } + if (vbr == 0 || constrained_vbr != 0) && isTransient == 0 { + i = start; + while i < end { + *follower.as_mut_ptr().offset(i as isize) = + 0.5f32 * *follower.as_mut_ptr().offset(i as isize); + i += 1; + } + } + i = start; + while i < end { + if i < 8 { + let ref mut fresh1 = *follower.as_mut_ptr().offset(i as isize); + *fresh1 *= 2 as f32; + } + if i >= 12 { + *follower.as_mut_ptr().offset(i as isize) = + 0.5f32 * *follower.as_mut_ptr().offset(i as isize); + } + i += 1; + } + if (*analysis).valid != 0 { + i = start; + while i < (if (19) < end { 19 } else { end }) { + *follower.as_mut_ptr().offset(i as isize) = + *follower.as_mut_ptr().offset(i as isize) + + 1.0f32 / 64.0f32 * (*analysis).leak_boost[i as usize] as i32 as f32; + i += 1; + } + } + i = start; + while i < end { + let mut width: i32 = 0; + let mut boost: i32 = 0; + let mut boost_bits: i32 = 0; + *follower.as_mut_ptr().offset(i as isize) = + if *follower.as_mut_ptr().offset(i as isize) < 4 as f32 { + *follower.as_mut_ptr().offset(i as isize) + } else { + 4 as f32 + }; + width = C + * (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32) + << LM; + if width < 6 { + boost = *follower.as_mut_ptr().offset(i as isize) as i32; + boost_bits = boost * width << BITRES; + } else if width > 48 { + boost = (*follower.as_mut_ptr().offset(i as isize) * 8 as f32) as i32; + boost_bits = (boost * width << BITRES) / 8; + } else { + boost = + (*follower.as_mut_ptr().offset(i as isize) * width as f32 / 6 as f32) as i32; + boost_bits = (boost * 6) << BITRES; + } + if (vbr == 0 || constrained_vbr != 0 && isTransient == 0) + && tot_boost + boost_bits >> BITRES >> 3 > 2 * effectiveBytes / 3 + { + let cap: i32 = (2 * effectiveBytes / 3) << BITRES << 3; + *offsets.offset(i as isize) = cap - tot_boost; + tot_boost = cap; + break; + } else { + *offsets.offset(i as isize) = boost; + tot_boost += boost_bits; + i += 1; + } + } + } else { + i = start; + while i < end { + *importance.offset(i as isize) = 13; + i += 1; + } + } + *tot_boost_ = tot_boost; + return maxDepth; +} +unsafe fn run_prefilter( + st: *mut OpusCustomEncoder, + in_0: *mut celt_sig, + prefilter_mem: *mut celt_sig, + CC: i32, + N: i32, + prefilter_tapset: i32, + pitch: *mut i32, + gain: *mut opus_val16, + qgain: *mut i32, + enabled: i32, + nbAvailableBytes: i32, + analysis: *mut AnalysisInfo, +) -> i32 { + let mut c: i32 = 0; + let mut pre: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2]; + let mut mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut pitch_index: i32 = 0; + let mut gain1: opus_val16 = 0.; + let mut pf_threshold: opus_val16 = 0.; + let mut pf_on: i32 = 0; + let mut qg: i32 = 0; + let mut overlap: i32 = 0; + mode = (*st).mode; + overlap = (*mode).overlap; + let vla = (CC * (N + 1024)) as usize; + let mut _pre: Vec = ::std::vec::from_elem(0., vla); + pre[0 as usize] = _pre.as_mut_ptr(); + pre[1 as usize] = _pre + .as_mut_ptr() + .offset((N + COMBFILTER_MAXPERIOD) as isize); + c = 0; + loop { + memcpy( + pre[c as usize] as *mut core::ffi::c_void, + prefilter_mem.offset((c * 1024) as isize) as *const core::ffi::c_void, + (1024_u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (pre[c as usize]).offset_from(prefilter_mem.offset((c * 1024) as isize)) + as i64) as u64, + ), + ); + memcpy( + (pre[c as usize]).offset(1024 as isize) as *mut core::ffi::c_void, + in_0.offset((c * (N + overlap)) as isize) + .offset(overlap as isize) as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (pre[c as usize]).offset(1024 as isize).offset_from( + in_0.offset((c * (N + overlap)) as isize) + .offset(overlap as isize), + ) as i64) as u64, + ), + ); + c += 1; + if !(c < CC) { + break; + } + } + if enabled != 0 { + let vla_0 = (1024 + N >> 1) as usize; + let mut pitch_buf: Vec = ::std::vec::from_elem(0., vla_0); + pitch_downsample( + pre.as_mut_ptr() as *mut *mut celt_sig, + pitch_buf.as_mut_ptr(), + COMBFILTER_MAXPERIOD + N, + CC, + (*st).arch, + ); + pitch_search( + pitch_buf + .as_mut_ptr() + .offset((COMBFILTER_MAXPERIOD >> 1) as isize), + pitch_buf.as_mut_ptr(), + N, + COMBFILTER_MAXPERIOD - 3 * COMBFILTER_MINPERIOD, + &mut pitch_index, + (*st).arch, + ); + pitch_index = COMBFILTER_MAXPERIOD - pitch_index; + gain1 = remove_doubling( + pitch_buf.as_mut_ptr(), + COMBFILTER_MAXPERIOD, + COMBFILTER_MINPERIOD, + N, + &mut pitch_index, + (*st).prefilter_period, + (*st).prefilter_gain, + (*st).arch, + ); + if pitch_index > COMBFILTER_MAXPERIOD - 2 { + pitch_index = COMBFILTER_MAXPERIOD - 2; + } + gain1 = 0.7f32 * gain1; + if (*st).loss_rate > 2 { + gain1 = 0.5f32 * gain1; + } + if (*st).loss_rate > 4 { + gain1 = 0.5f32 * gain1; + } + if (*st).loss_rate > 8 { + gain1 = 0 as opus_val16; + } + } else { + gain1 = 0 as opus_val16; + pitch_index = COMBFILTER_MINPERIOD; + } + if (*analysis).valid != 0 { + gain1 = gain1 * (*analysis).max_pitch_ratio; + } + pf_threshold = 0.2f32; + if (pitch_index - (*st).prefilter_period).abs() * 10 > pitch_index { + pf_threshold += 0.2f32; + } + if nbAvailableBytes < 25 { + pf_threshold += 0.1f32; + } + if nbAvailableBytes < 35 { + pf_threshold += 0.1f32; + } + if (*st).prefilter_gain > 0.4f32 { + pf_threshold -= 0.1f32; + } + if (*st).prefilter_gain > 0.55f32 { + pf_threshold -= 0.1f32; + } + pf_threshold = if pf_threshold > 0.2f32 { + pf_threshold + } else { + 0.2f32 + }; + if gain1 < pf_threshold { + gain1 = 0 as opus_val16; + pf_on = 0; + qg = 0; + } else { + if ((gain1 - (*st).prefilter_gain).abs()) < 0.1f32 { + gain1 = (*st).prefilter_gain; + } + qg = (0.5f32 + gain1 * 32 as f32 / 3 as f32).floor() as i32 - 1; + qg = if 0 > (if (7) < qg { 7 } else { qg }) { + 0 + } else if (7) < qg { + 7 + } else { + qg + }; + gain1 = 0.09375f32 * (qg + 1) as f32; + pf_on = 1; + } + c = 0; + loop { + let offset: i32 = (*mode).shortMdctSize - overlap; + (*st).prefilter_period = if (*st).prefilter_period > 15 { + (*st).prefilter_period + } else { + 15 + }; + memcpy( + in_0.offset((c * (N + overlap)) as isize) as *mut core::ffi::c_void, + ((*st).in_mem).as_mut_ptr().offset((c * overlap) as isize) as *const core::ffi::c_void, + (overlap as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * in_0 + .offset((c * (N + overlap)) as isize) + .offset_from(((*st).in_mem).as_mut_ptr().offset((c * overlap) as isize)) + as i64) as u64, + ), + ); + if offset != 0 { + comb_filter( + in_0.offset((c * (N + overlap)) as isize) + .offset(overlap as isize), + (pre[c as usize]).offset(COMBFILTER_MAXPERIOD as isize), + (*st).prefilter_period, + (*st).prefilter_period, + offset, + -(*st).prefilter_gain, + -(*st).prefilter_gain, + (*st).prefilter_tapset, + (*st).prefilter_tapset, + NULL as *const opus_val16, + 0, + (*st).arch, + ); + } + comb_filter( + in_0.offset((c * (N + overlap)) as isize) + .offset(overlap as isize) + .offset(offset as isize), + (pre[c as usize]) + .offset(COMBFILTER_MAXPERIOD as isize) + .offset(offset as isize), + (*st).prefilter_period, + pitch_index, + N - offset, + -(*st).prefilter_gain, + -gain1, + (*st).prefilter_tapset, + prefilter_tapset, + (*mode).window, + overlap, + (*st).arch, + ); + memcpy( + ((*st).in_mem).as_mut_ptr().offset((c * overlap) as isize) as *mut core::ffi::c_void, + in_0.offset((c * (N + overlap)) as isize).offset(N as isize) + as *const core::ffi::c_void, + (overlap as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * ((*st).in_mem) + .as_mut_ptr() + .offset((c * overlap) as isize) + .offset_from(in_0.offset((c * (N + overlap)) as isize).offset(N as isize)) + as i64) as u64, + ), + ); + if N > COMBFILTER_MAXPERIOD { + memcpy( + prefilter_mem.offset((c * 1024) as isize) as *mut core::ffi::c_void, + (pre[c as usize]).offset(N as isize) as *const core::ffi::c_void, + (1024_u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * prefilter_mem + .offset((c * 1024) as isize) + .offset_from((pre[c as usize]).offset(N as isize)) + as i64) as u64, + ), + ); + } else { + memmove( + prefilter_mem.offset((c * 1024) as isize) as *mut core::ffi::c_void, + prefilter_mem.offset((c * 1024) as isize).offset(N as isize) + as *const core::ffi::c_void, + ((1024 - N) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * prefilter_mem.offset((c * 1024) as isize).offset_from( + prefilter_mem.offset((c * 1024) as isize).offset(N as isize), + ) as i64) as u64, + ), + ); + memcpy( + prefilter_mem + .offset((c * 1024) as isize) + .offset(1024 as isize) + .offset(-(N as isize)) as *mut core::ffi::c_void, + (pre[c as usize]).offset(1024 as isize) as *const core::ffi::c_void, + (N as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * prefilter_mem + .offset((c * 1024) as isize) + .offset(1024 as isize) + .offset(-(N as isize)) + .offset_from((pre[c as usize]).offset(1024 as isize)) + as i64) as u64, + ), + ); + } + c += 1; + if !(c < CC) { + break; + } + } + *gain = gain1; + *pitch = pitch_index; + *qgain = qg; + return pf_on; +} +unsafe fn compute_vbr( + mode: *const OpusCustomMode, + analysis: *mut AnalysisInfo, + base_target: i32, + LM: i32, + bitrate: i32, + lastCodedBands: i32, + C: i32, + intensity: i32, + constrained_vbr: i32, + mut stereo_saving: opus_val16, + tot_boost: i32, + tf_estimate: opus_val16, + pitch_change: i32, + maxDepth: opus_val16, + lfe: i32, + has_surround_mask: i32, + surround_masking: opus_val16, + temporal_vbr: opus_val16, +) -> i32 { + let mut target: i32 = 0; + let mut coded_bins: i32 = 0; + let mut coded_bands: i32 = 0; + let mut tf_calibration: opus_val16 = 0.; + let mut nbEBands: i32 = 0; + let mut eBands: *const i16 = 0 as *const i16; + nbEBands = (*mode).nbEBands; + eBands = (*mode).eBands; + coded_bands = if lastCodedBands != 0 { + lastCodedBands + } else { + nbEBands + }; + coded_bins = (*eBands.offset(coded_bands as isize) as i32) << LM; + if C == 2 { + coded_bins += (*eBands.offset( + (if intensity < coded_bands { + intensity + } else { + coded_bands + }) as isize, + ) as i32) + << LM; + } + target = base_target; + if (*analysis).valid != 0 && ((*analysis).activity as f64) < 0.4f64 { + target -= ((coded_bins << BITRES) as f32 * (0.4f32 - (*analysis).activity)) as i32; + } + if C == 2 { + let mut coded_stereo_bands: i32 = 0; + let mut coded_stereo_dof: i32 = 0; + let mut max_frac: opus_val16 = 0.; + coded_stereo_bands = if intensity < coded_bands { + intensity + } else { + coded_bands + }; + coded_stereo_dof = + ((*eBands.offset(coded_stereo_bands as isize) as i32) << LM) - coded_stereo_bands; + max_frac = 0.8f32 * coded_stereo_dof as opus_val32 / coded_bins as opus_val16; + stereo_saving = if stereo_saving < 1.0f32 { + stereo_saving + } else { + 1.0f32 + }; + target -= (if (max_frac * target as f32) + < (stereo_saving - 0.1f32) * (coded_stereo_dof << 3) as opus_val32 + { + max_frac * target as f32 + } else { + (stereo_saving - 0.1f32) * (coded_stereo_dof << 3) as opus_val32 + }) as i32; + } + target += tot_boost - ((19) << LM); + tf_calibration = 0.044f32; + target += ((tf_estimate - tf_calibration) * target as f32) as i32; + if (*analysis).valid != 0 && lfe == 0 { + let mut tonal_target: i32 = 0; + let mut tonal: f32 = 0.; + tonal = (if 0.0f32 > (*analysis).tonality - 0.15f32 { + 0.0f32 + } else { + (*analysis).tonality - 0.15f32 + }) - 0.12f32; + tonal_target = target + ((coded_bins << BITRES) as f32 * 1.2f32 * tonal) as i32; + if pitch_change != 0 { + tonal_target += ((coded_bins << BITRES) as f32 * 0.8f32) as i32; + } + target = tonal_target; + } + if has_surround_mask != 0 && lfe == 0 { + let surround_target: i32 = + target + (surround_masking * (coded_bins << 3) as opus_val32) as i32; + target = if target / 4 > surround_target { + target / 4 + } else { + surround_target + }; + } + let mut floor_depth: i32 = 0; + let mut bins: i32 = 0; + bins = (*eBands.offset((nbEBands - 2) as isize) as i32) << LM; + floor_depth = ((C * bins << 3) as opus_val32 * maxDepth) as i32; + floor_depth = if floor_depth > target >> 2 { + floor_depth + } else { + target >> 2 + }; + target = if target < floor_depth { + target + } else { + floor_depth + }; + if (has_surround_mask == 0 || lfe != 0) && constrained_vbr != 0 { + target = base_target + (0.67f32 * (target - base_target) as f32) as i32; + } + if has_surround_mask == 0 && tf_estimate < 0.2f32 { + let mut amount: opus_val16 = 0.; + let mut tvbr_factor: opus_val16 = 0.; + amount = 0.0000031f32 + * (if 0 + > (if (32000) < 96000 - bitrate { + 32000 + } else { + 96000 - bitrate + }) + { + 0 + } else { + if (32000) < 96000 - bitrate { + 32000 + } else { + 96000 - bitrate + } + }) as f32; + tvbr_factor = temporal_vbr * amount; + target += (tvbr_factor * target as f32) as i32; + } + target = if 2 * base_target < target { + 2 * base_target + } else { + target + }; + return target; +} +pub unsafe fn celt_encode_with_ec( + st: *mut OpusCustomEncoder, + pcm: *const opus_val16, + mut frame_size: i32, + compressed: *mut u8, + mut nbCompressedBytes: i32, + mut enc: Option<&mut ec_enc>, +) -> i32 { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut N: i32 = 0; + let mut bits: i32 = 0; + let mut _enc: ec_enc = ec_enc { + buf: &mut [], + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut prefilter_mem: *mut celt_sig = 0 as *mut celt_sig; + let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16; + let mut energyError: *mut opus_val16 = 0 as *mut opus_val16; + let mut shortBlocks: i32 = 0; + let mut isTransient: i32 = 0; + let CC: i32 = (*st).channels; + let C: i32 = (*st).stream_channels; + let mut LM: i32 = 0; + let mut M: i32 = 0; + let mut tf_select: i32 = 0; + let mut nbFilledBytes: i32 = 0; + let mut nbAvailableBytes: i32 = 0; + let mut start: i32 = 0; + let mut end: i32 = 0; + let mut effEnd: i32 = 0; + let mut codedBands: i32 = 0; + let mut alloc_trim: i32 = 0; + let mut pitch_index: i32 = COMBFILTER_MINPERIOD; + let mut gain1: opus_val16 = 0 as opus_val16; + let mut dual_stereo: i32 = 0; + let mut effectiveBytes: i32 = 0; + let mut dynalloc_logp: i32 = 0; + let mut vbr_rate: i32 = 0; + let mut total_bits: i32 = 0; + let mut total_boost: i32 = 0; + let mut balance: i32 = 0; + let mut tell: i32 = 0; + let mut tell0_frac: i32 = 0; + let mut prefilter_tapset: i32 = 0; + let mut pf_on: i32 = 0; + let mut anti_collapse_rsv: i32 = 0; + let mut anti_collapse_on: i32 = 0; + let mut silence: i32 = 0; + let mut tf_chan: i32 = 0; + let mut tf_estimate: opus_val16 = 0.; + let mut pitch_change: i32 = 0; + let mut tot_boost: i32 = 0; + let mut sample_max: opus_val32 = 0.; + let mut maxDepth: opus_val16 = 0.; + let mut mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut nbEBands: i32 = 0; + let mut overlap: i32 = 0; + let mut eBands: *const i16 = 0 as *const i16; + let mut secondMdct: i32 = 0; + let mut signalBandwidth: i32 = 0; + let mut transient_got_disabled: i32 = 0; + let mut surround_masking: opus_val16 = 0 as opus_val16; + let mut temporal_vbr: opus_val16 = 0 as opus_val16; + let mut surround_trim: opus_val16 = 0 as opus_val16; + let mut equiv_rate: i32 = 0; + let mut hybrid: i32 = 0; + let mut weak_transient: i32 = 0; + let mut enable_tf_analysis: i32 = 0; + mode = (*st).mode; + nbEBands = (*mode).nbEBands; + overlap = (*mode).overlap; + eBands = (*mode).eBands; + start = (*st).start; + end = (*st).end; + hybrid = (start != 0) as i32; + tf_estimate = 0 as opus_val16; + if nbCompressedBytes < 2 || pcm.is_null() { + return OPUS_BAD_ARG; + } + frame_size *= (*st).upsample; + LM = 0; + while LM <= (*mode).maxLM { + if (*mode).shortMdctSize << LM == frame_size { + break; + } + LM += 1; + } + if LM > (*mode).maxLM { + return OPUS_BAD_ARG; + } + M = (1) << LM; + N = M * (*mode).shortMdctSize; + prefilter_mem = ((*st).in_mem).as_mut_ptr().offset((CC * overlap) as isize); + oldBandE = ((*st).in_mem) + .as_mut_ptr() + .offset((CC * (overlap + COMBFILTER_MAXPERIOD)) as isize) as *mut opus_val16; + oldLogE = oldBandE.offset((CC * nbEBands) as isize); + oldLogE2 = oldLogE.offset((CC * nbEBands) as isize); + energyError = oldLogE2.offset((CC * nbEBands) as isize); + if let Some(enc) = enc.as_mut() { + tell0_frac = ec_tell_frac(*enc) as i32; + tell = ec_tell(*enc); + nbFilledBytes = tell + 4 >> 3; + } else { + tell = 1; + tell0_frac = tell; + nbFilledBytes = 0; + } + assert!((*st).signalling == 0); + nbCompressedBytes = if nbCompressedBytes < 1275 { + nbCompressedBytes + } else { + 1275 + }; + nbAvailableBytes = nbCompressedBytes - nbFilledBytes; + if (*st).vbr != 0 && (*st).bitrate != OPUS_BITRATE_MAX { + let den: i32 = (*mode).Fs >> BITRES; + vbr_rate = ((*st).bitrate * frame_size + (den >> 1)) / den; + effectiveBytes = vbr_rate >> 3 + BITRES; + } else { + let mut tmp: i32 = 0; + vbr_rate = 0; + tmp = (*st).bitrate * frame_size; + if tell > 1 { + tmp += tell; + } + if (*st).bitrate != OPUS_BITRATE_MAX { + nbCompressedBytes = if 2 + > (if nbCompressedBytes + < (tmp + 4 * (*mode).Fs) / (8 * (*mode).Fs) - ((*st).signalling != 0) as i32 + { + nbCompressedBytes + } else { + (tmp + 4 * (*mode).Fs) / (8 * (*mode).Fs) - ((*st).signalling != 0) as i32 + }) { + 2 + } else if nbCompressedBytes + < (tmp + 4 * (*mode).Fs) / (8 * (*mode).Fs) - ((*st).signalling != 0) as i32 + { + nbCompressedBytes + } else { + (tmp + 4 * (*mode).Fs) / (8 * (*mode).Fs) - ((*st).signalling != 0) as i32 + }; + } + effectiveBytes = nbCompressedBytes - nbFilledBytes; + } + equiv_rate = (nbCompressedBytes * 8 * 50 >> 3 - LM) - (40 * C + 20) * ((400 >> LM) - 50); + if (*st).bitrate != OPUS_BITRATE_MAX { + equiv_rate = if equiv_rate < (*st).bitrate - (40 * C + 20) * ((400 >> LM) - 50) { + equiv_rate + } else { + (*st).bitrate - (40 * C + 20) * ((400 >> LM) - 50) + }; + } + let enc = if let Some(enc) = enc { + enc + } else { + assert!(!compressed.is_null()); + _enc = ec_enc_init(std::slice::from_raw_parts_mut( + compressed, + nbCompressedBytes as usize, + )); + &mut _enc + }; + if vbr_rate > 0 { + if (*st).constrained_vbr != 0 { + let mut vbr_bound: i32 = 0; + let mut max_allowed: i32 = 0; + vbr_bound = vbr_rate; + max_allowed = if (if (if tell == 1 { 2 } else { 0 }) + > vbr_rate + vbr_bound - (*st).vbr_reservoir >> 3 + 3 + { + if tell == 1 { + 2 + } else { + 0 + } + } else { + vbr_rate + vbr_bound - (*st).vbr_reservoir >> 3 + 3 + }) < nbAvailableBytes + { + if (if tell == 1 { 2 } else { 0 }) + > vbr_rate + vbr_bound - (*st).vbr_reservoir >> 3 + 3 + { + if tell == 1 { + 2 + } else { + 0 + } + } else { + vbr_rate + vbr_bound - (*st).vbr_reservoir >> 3 + 3 + } + } else { + nbAvailableBytes + }; + if max_allowed < nbAvailableBytes { + nbCompressedBytes = nbFilledBytes + max_allowed; + nbAvailableBytes = max_allowed; + ec_enc_shrink(enc, nbCompressedBytes as u32); + } + } + } + total_bits = nbCompressedBytes * 8; + effEnd = end; + if effEnd > (*mode).effEBands { + effEnd = (*mode).effEBands; + } + let vla = (CC * (N + overlap)) as usize; + let mut in_0: Vec = ::std::vec::from_elem(0., vla); + sample_max = if (*st).overlap_max > celt_maxabs16(pcm, C * (N - overlap) / (*st).upsample) { + (*st).overlap_max + } else { + celt_maxabs16(pcm, C * (N - overlap) / (*st).upsample) + }; + (*st).overlap_max = celt_maxabs16( + pcm.offset((C * (N - overlap) / (*st).upsample) as isize), + C * overlap / (*st).upsample, + ); + sample_max = if sample_max > (*st).overlap_max { + sample_max + } else { + (*st).overlap_max + }; + silence = (sample_max <= 1 as opus_val16 / ((1) << (*st).lsb_depth) as f32) as i32; + if tell == 1 { + ec_enc_bit_logp(enc, silence, 15); + } else { + silence = 0; + } + if silence != 0 { + if vbr_rate > 0 { + nbCompressedBytes = if nbCompressedBytes < nbFilledBytes + 2 { + nbCompressedBytes + } else { + nbFilledBytes + 2 + }; + effectiveBytes = nbCompressedBytes; + total_bits = nbCompressedBytes * 8; + nbAvailableBytes = 2; + ec_enc_shrink(enc, nbCompressedBytes as u32); + } + tell = nbCompressedBytes * 8; + (*enc).nbits_total += tell - ec_tell(enc); + } + c = 0; + loop { + let mut need_clip: i32 = 0; + need_clip = ((*st).clip != 0 && sample_max > 65536.0f32) as i32; + celt_preemphasis( + pcm.offset(c as isize), + in_0.as_mut_ptr() + .offset((c * (N + overlap)) as isize) + .offset(overlap as isize), + N, + CC, + (*st).upsample, + ((*mode).preemph).as_ptr(), + ((*st).preemph_memE).as_mut_ptr().offset(c as isize), + need_clip, + ); + c += 1; + if !(c < CC) { + break; + } + } + let mut enabled: i32 = 0; + let mut qg: i32 = 0; + enabled = (((*st).lfe != 0 && nbAvailableBytes > 3 || nbAvailableBytes > 12 * C) + && hybrid == 0 + && silence == 0 + && (*st).disable_pf == 0 + && (*st).complexity >= 5) as i32; + prefilter_tapset = (*st).tapset_decision; + pf_on = run_prefilter( + st, + in_0.as_mut_ptr(), + prefilter_mem, + CC, + N, + prefilter_tapset, + &mut pitch_index, + &mut gain1, + &mut qg, + enabled, + nbAvailableBytes, + &mut (*st).analysis, + ); + #[cfg(feature = "ent-dump")] + eprintln!("prefilter: pitch_index={pitch_index}, gain1={gain1:1.6}, qg={qg}"); + if (gain1 > 0.4f32 || (*st).prefilter_gain > 0.4f32) + && ((*st).analysis.valid == 0 || (*st).analysis.tonality as f64 > 0.3f64) + && (pitch_index as f64 > 1.26f64 * (*st).prefilter_period as f64 + || (pitch_index as f64) < 0.79f64 * (*st).prefilter_period as f64) + { + pitch_change = 1; + } + if pf_on == 0 { + if hybrid == 0 && tell + 16 <= total_bits { + ec_enc_bit_logp(enc, 0, 1); + } + } else { + let mut octave: i32 = 0; + ec_enc_bit_logp(enc, 1, 1); + pitch_index += 1; + octave = EC_CLZ0 - (pitch_index as u32).leading_zeros() as i32 - 5; + ec_enc_uint(enc, octave as u32, 6); + ec_enc_bits( + enc, + (pitch_index - ((16) << octave)) as u32, + (4 + octave) as u32, + ); + pitch_index -= 1; + ec_enc_bits(enc, qg as u32, 3); + ec_enc_icdf(enc, prefilter_tapset, &tapset_icdf, 2); + } + isTransient = 0; + shortBlocks = 0; + if (*st).complexity >= 1 && (*st).lfe == 0 { + let allow_weak_transients: i32 = + (hybrid != 0 && effectiveBytes < 15 && (*st).silk_info.signalType != 2) as i32; + isTransient = transient_analysis( + in_0.as_mut_ptr(), + N + overlap, + CC, + &mut tf_estimate, + &mut tf_chan, + allow_weak_transients, + &mut weak_transient, + ); + } + if LM > 0 && ec_tell(enc) + 3 <= total_bits { + if isTransient != 0 { + shortBlocks = M; + } + } else { + isTransient = 0; + transient_got_disabled = 1; + } + let vla_0 = (CC * N) as usize; + let mut freq: Vec = ::std::vec::from_elem(0., vla_0); + let vla_1 = (nbEBands * CC) as usize; + let mut bandE: Vec = ::std::vec::from_elem(0., vla_1); + let vla_2 = (nbEBands * CC) as usize; + let mut bandLogE: Vec = ::std::vec::from_elem(0., vla_2); + secondMdct = (shortBlocks != 0 && (*st).complexity >= 8) as i32; + let vla_3 = (C * nbEBands) as usize; + let mut bandLogE2: Vec = ::std::vec::from_elem(0., vla_3); + if secondMdct != 0 { + compute_mdcts( + mode, + 0, + in_0.as_mut_ptr(), + freq.as_mut_ptr(), + C, + CC, + LM, + (*st).upsample, + (*st).arch, + ); + compute_band_energies( + mode, + freq.as_mut_ptr(), + bandE.as_mut_ptr(), + effEnd, + C, + LM, + (*st).arch, + ); + amp2Log2( + mode, + effEnd, + end, + bandE.as_mut_ptr(), + bandLogE2.as_mut_ptr(), + C, + ); + i = 0; + while i < C * nbEBands { + let ref mut fresh2 = *bandLogE2.as_mut_ptr().offset(i as isize); + *fresh2 += 0.5f32 * LM as f32; + i += 1; + } + } + compute_mdcts( + mode, + shortBlocks, + in_0.as_mut_ptr(), + freq.as_mut_ptr(), + C, + CC, + LM, + (*st).upsample, + (*st).arch, + ); + assert!( + !(*freq.as_mut_ptr().offset(0 as isize) != *freq.as_mut_ptr().offset(0 as isize)) + && (C == 1 + || !(*freq.as_mut_ptr().offset(N as isize) + != *freq.as_mut_ptr().offset(N as isize))) + ); + if CC == 2 && C == 1 { + tf_chan = 0; + } + compute_band_energies( + mode, + freq.as_mut_ptr(), + bandE.as_mut_ptr(), + effEnd, + C, + LM, + (*st).arch, + ); + if (*st).lfe != 0 { + i = 2; + while i < end { + *bandE.as_mut_ptr().offset(i as isize) = if *bandE.as_mut_ptr().offset(i as isize) + < 1e-4f32 * *bandE.as_mut_ptr().offset(0 as isize) + { + *bandE.as_mut_ptr().offset(i as isize) + } else { + 1e-4f32 * *bandE.as_mut_ptr().offset(0 as isize) + }; + *bandE.as_mut_ptr().offset(i as isize) = + if *bandE.as_mut_ptr().offset(i as isize) > 1e-15f32 { + *bandE.as_mut_ptr().offset(i as isize) + } else { + 1e-15f32 + }; + i += 1; + } + } + amp2Log2( + mode, + effEnd, + end, + bandE.as_mut_ptr(), + bandLogE.as_mut_ptr(), + C, + ); + let vla_4 = (C * nbEBands) as usize; + let mut surround_dynalloc: Vec = ::std::vec::from_elem(0., vla_4); + memset( + surround_dynalloc.as_mut_ptr() as *mut core::ffi::c_void, + 0, + (end as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + if hybrid == 0 && !((*st).energy_mask).is_null() && (*st).lfe == 0 { + let mut mask_end: i32 = 0; + let mut midband: i32 = 0; + let mut count_dynalloc: i32 = 0; + let mut mask_avg: opus_val32 = 0 as opus_val32; + let mut diff: opus_val32 = 0 as opus_val32; + let mut count: i32 = 0; + mask_end = if 2 > (*st).lastCodedBands { + 2 + } else { + (*st).lastCodedBands + }; + c = 0; + while c < C { + i = 0; + while i < mask_end { + let mut mask: opus_val16 = 0.; + mask = if (if *((*st).energy_mask).offset((nbEBands * c + i) as isize) < 0.25f32 { + *((*st).energy_mask).offset((nbEBands * c + i) as isize) + } else { + 0.25f32 + }) > -2.0f32 + { + if *((*st).energy_mask).offset((nbEBands * c + i) as isize) < 0.25f32 { + *((*st).energy_mask).offset((nbEBands * c + i) as isize) + } else { + 0.25f32 + } + } else { + -2.0f32 + }; + if mask > 0 as f32 { + mask = 0.5f32 * mask; + } + mask_avg += mask + * (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32) + as opus_val32; + count += + *eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32; + diff += mask * (1 + 2 * i - mask_end) as opus_val32; + i += 1; + } + c += 1; + } + assert!(count > 0); + mask_avg = mask_avg / count as opus_val16; + mask_avg += 0.2f32; + diff = diff * 6 as f32 / (C * (mask_end - 1) * (mask_end + 1) * mask_end) as f32; + diff = 0.5f32 * diff; + diff = if (if diff < 0.031f32 { diff } else { 0.031f32 }) > -0.031f32 { + if diff < 0.031f32 { + diff + } else { + 0.031f32 + } + } else { + -0.031f32 + }; + midband = 0; + while (*eBands.offset((midband + 1) as isize) as i32) + < *eBands.offset(mask_end as isize) as i32 / 2 + { + midband += 1; + } + count_dynalloc = 0; + i = 0; + while i < mask_end { + let mut lin: opus_val32 = 0.; + let mut unmask: opus_val16 = 0.; + lin = mask_avg + diff * (i - midband) as f32; + if C == 2 { + unmask = if *((*st).energy_mask).offset(i as isize) + > *((*st).energy_mask).offset((nbEBands + i) as isize) + { + *((*st).energy_mask).offset(i as isize) + } else { + *((*st).energy_mask).offset((nbEBands + i) as isize) + }; + } else { + unmask = *((*st).energy_mask).offset(i as isize); + } + unmask = if unmask < 0.0f32 { unmask } else { 0.0f32 }; + unmask -= lin; + if unmask > 0.25f32 { + *surround_dynalloc.as_mut_ptr().offset(i as isize) = unmask - 0.25f32; + count_dynalloc += 1; + } + i += 1; + } + if count_dynalloc >= 3 { + mask_avg += 0.25f32; + if mask_avg > 0 as f32 { + mask_avg = 0 as opus_val32; + diff = 0 as opus_val32; + memset( + surround_dynalloc.as_mut_ptr() as *mut core::ffi::c_void, + 0, + (mask_end as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } else { + i = 0; + while i < mask_end { + *surround_dynalloc.as_mut_ptr().offset(i as isize) = if 0 as f32 + > *surround_dynalloc.as_mut_ptr().offset(i as isize) - 0.25f32 + { + 0 as f32 + } else { + *surround_dynalloc.as_mut_ptr().offset(i as isize) - 0.25f32 + }; + i += 1; + } + } + } + mask_avg += 0.2f32; + surround_trim = 64 as f32 * diff; + surround_masking = mask_avg; + } + if (*st).lfe == 0 { + let mut follow: opus_val16 = -10.0f32; + let mut frame_avg: opus_val32 = 0 as opus_val32; + let offset: opus_val16 = if shortBlocks != 0 { + 0.5f32 * LM as f32 + } else { + 0 as f32 + }; + i = start; + while i < end { + follow = if follow - 1.0f32 > *bandLogE.as_mut_ptr().offset(i as isize) - offset { + follow - 1.0f32 + } else { + *bandLogE.as_mut_ptr().offset(i as isize) - offset + }; + if C == 2 { + follow = if follow > *bandLogE.as_mut_ptr().offset((i + nbEBands) as isize) - offset + { + follow + } else { + *bandLogE.as_mut_ptr().offset((i + nbEBands) as isize) - offset + }; + } + frame_avg += follow; + i += 1; + } + frame_avg /= (end - start) as f32; + temporal_vbr = frame_avg - (*st).spec_avg; + temporal_vbr = if 3.0f32 + < (if -1.5f32 > temporal_vbr { + -1.5f32 + } else { + temporal_vbr + }) { + 3.0f32 + } else if -1.5f32 > temporal_vbr { + -1.5f32 + } else { + temporal_vbr + }; + (*st).spec_avg += 0.02f32 * temporal_vbr; + } + if secondMdct == 0 { + memcpy( + bandLogE2.as_mut_ptr() as *mut core::ffi::c_void, + bandLogE.as_mut_ptr() as *const core::ffi::c_void, + ((C * nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * bandLogE2.as_mut_ptr().offset_from(bandLogE.as_mut_ptr()) as i64) as u64, + ), + ); + } + if LM > 0 + && ec_tell(enc) + 3 <= total_bits + && isTransient == 0 + && (*st).complexity >= 5 + && (*st).lfe == 0 + && hybrid == 0 + { + if patch_transient_decision(bandLogE.as_mut_ptr(), oldBandE, nbEBands, start, end, C) != 0 { + isTransient = 1; + shortBlocks = M; + compute_mdcts( + mode, + shortBlocks, + in_0.as_mut_ptr(), + freq.as_mut_ptr(), + C, + CC, + LM, + (*st).upsample, + (*st).arch, + ); + compute_band_energies( + mode, + freq.as_mut_ptr(), + bandE.as_mut_ptr(), + effEnd, + C, + LM, + (*st).arch, + ); + amp2Log2( + mode, + effEnd, + end, + bandE.as_mut_ptr(), + bandLogE.as_mut_ptr(), + C, + ); + i = 0; + while i < C * nbEBands { + let ref mut fresh3 = *bandLogE2.as_mut_ptr().offset(i as isize); + *fresh3 += 0.5f32 * LM as f32; + i += 1; + } + tf_estimate = 0.2f32; + } + } + if LM > 0 && ec_tell(enc) + 3 <= total_bits { + ec_enc_bit_logp(enc, isTransient, 3); + } + let vla_5 = (C * N) as usize; + let mut X: Vec = ::std::vec::from_elem(0., vla_5); + normalise_bands( + mode, + freq.as_mut_ptr(), + X.as_mut_ptr(), + bandE.as_mut_ptr(), + effEnd, + C, + M, + ); + enable_tf_analysis = + (effectiveBytes >= 15 * C && hybrid == 0 && (*st).complexity >= 2 && (*st).lfe == 0) as i32; + let vla_6 = nbEBands as usize; + let mut offsets: Vec = ::std::vec::from_elem(0, vla_6); + let vla_7 = nbEBands as usize; + let mut importance: Vec = ::std::vec::from_elem(0, vla_7); + let vla_8 = nbEBands as usize; + let mut spread_weight: Vec = ::std::vec::from_elem(0, vla_8); + maxDepth = dynalloc_analysis( + bandLogE.as_mut_ptr(), + bandLogE2.as_mut_ptr(), + nbEBands, + start, + end, + C, + offsets.as_mut_ptr(), + (*st).lsb_depth, + (*mode).logN, + isTransient, + (*st).vbr, + (*st).constrained_vbr, + eBands, + LM, + effectiveBytes, + &mut tot_boost, + (*st).lfe, + surround_dynalloc.as_mut_ptr(), + &mut (*st).analysis, + importance.as_mut_ptr(), + spread_weight.as_mut_ptr(), + ); + let vla_9 = nbEBands as usize; + let mut tf_res: Vec = ::std::vec::from_elem(0, vla_9); + if enable_tf_analysis != 0 { + let mut lambda: i32 = 0; + lambda = if 80 > 20480 / effectiveBytes + 2 { + 80 + } else { + 20480 / effectiveBytes + 2 + }; + tf_select = tf_analysis( + mode, + effEnd, + isTransient, + tf_res.as_mut_ptr(), + lambda, + X.as_mut_ptr(), + N, + LM, + tf_estimate, + tf_chan, + importance.as_mut_ptr(), + ); + i = effEnd; + while i < end { + *tf_res.as_mut_ptr().offset(i as isize) = + *tf_res.as_mut_ptr().offset((effEnd - 1) as isize); + i += 1; + } + } else if hybrid != 0 && weak_transient != 0 { + i = 0; + while i < end { + *tf_res.as_mut_ptr().offset(i as isize) = 1; + i += 1; + } + tf_select = 0; + } else if hybrid != 0 && effectiveBytes < 15 && (*st).silk_info.signalType != 2 { + i = 0; + while i < end { + *tf_res.as_mut_ptr().offset(i as isize) = 0; + i += 1; + } + tf_select = isTransient; + } else { + i = 0; + while i < end { + *tf_res.as_mut_ptr().offset(i as isize) = isTransient; + i += 1; + } + tf_select = 0; + } + let vla_10 = (C * nbEBands) as usize; + let mut error: Vec = ::std::vec::from_elem(0., vla_10); + c = 0; + loop { + i = start; + while i < end { + if (*bandLogE.as_mut_ptr().offset((i + c * nbEBands) as isize) + - *oldBandE.offset((i + c * nbEBands) as isize)) + .abs() + < 2.0f32 + { + let ref mut fresh4 = *bandLogE.as_mut_ptr().offset((i + c * nbEBands) as isize); + *fresh4 -= *energyError.offset((i + c * nbEBands) as isize) * 0.25f32; + } + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + quant_coarse_energy( + mode, + start, + end, + effEnd, + bandLogE.as_mut_ptr(), + oldBandE, + total_bits as u32, + error.as_mut_ptr(), + enc, + C, + LM, + nbAvailableBytes, + (*st).force_intra, + &mut (*st).delayedIntra, + ((*st).complexity >= 4) as i32, + (*st).loss_rate, + (*st).lfe, + ); + tf_encode( + start, + end, + isTransient, + tf_res.as_mut_ptr(), + LM, + tf_select, + enc, + ); + if ec_tell(enc) + 4 <= total_bits { + if (*st).lfe != 0 { + (*st).tapset_decision = 0; + (*st).spread_decision = SPREAD_NORMAL; + } else if hybrid != 0 { + if (*st).complexity == 0 { + (*st).spread_decision = SPREAD_NONE; + } else if isTransient != 0 { + (*st).spread_decision = SPREAD_NORMAL; + } else { + (*st).spread_decision = SPREAD_AGGRESSIVE; + } + } else if shortBlocks != 0 || (*st).complexity < 3 || nbAvailableBytes < 10 * C { + if (*st).complexity == 0 { + (*st).spread_decision = SPREAD_NONE; + } else { + (*st).spread_decision = SPREAD_NORMAL; + } + } else { + (*st).spread_decision = spreading_decision( + mode, + X.as_mut_ptr(), + &mut (*st).tonal_average, + (*st).spread_decision, + &mut (*st).hf_average, + &mut (*st).tapset_decision, + (pf_on != 0 && shortBlocks == 0) as i32, + effEnd, + C, + M, + spread_weight.as_mut_ptr(), + ); + } + ec_enc_icdf(enc, (*st).spread_decision, &spread_icdf, 5); + } + if (*st).lfe != 0 { + *offsets.as_mut_ptr().offset(0 as isize) = if (8) < effectiveBytes / 3 { + 8 + } else { + effectiveBytes / 3 + }; + } + let vla_11 = nbEBands as usize; + let mut cap: Vec = ::std::vec::from_elem(0, vla_11); + init_caps(mode, cap.as_mut_ptr(), LM, C); + dynalloc_logp = 6; + total_bits <<= BITRES; + total_boost = 0; + tell = ec_tell_frac(enc) as i32; + i = start; + while i < end { + let mut width: i32 = 0; + let mut quanta: i32 = 0; + let mut dynalloc_loop_logp: i32 = 0; + let mut boost: i32 = 0; + let mut j: i32 = 0; + width = + C * (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32) << LM; + quanta = if (width << 3) < (if (6) << 3 > width { (6) << 3 } else { width }) { + width << 3 + } else if (6) << 3 > width { + (6) << 3 + } else { + width + }; + dynalloc_loop_logp = dynalloc_logp; + boost = 0; + j = 0; + while tell + (dynalloc_loop_logp << BITRES) < total_bits - total_boost + && boost < *cap.as_mut_ptr().offset(i as isize) + { + let mut flag: i32 = 0; + flag = (j < *offsets.as_mut_ptr().offset(i as isize)) as i32; + ec_enc_bit_logp(enc, flag, dynalloc_loop_logp as u32); + tell = ec_tell_frac(enc) as i32; + if flag == 0 { + break; + } + boost += quanta; + total_boost += quanta; + dynalloc_loop_logp = 1; + j += 1; + } + if j != 0 { + dynalloc_logp = if 2 > dynalloc_logp - 1 { + 2 + } else { + dynalloc_logp - 1 + }; + } + *offsets.as_mut_ptr().offset(i as isize) = boost; + i += 1; + } + if C == 2 { + static mut intensity_thresholds: [opus_val16; 21] = [ + 1 as opus_val16, + 2 as opus_val16, + 3 as opus_val16, + 4 as opus_val16, + 5 as opus_val16, + 6 as opus_val16, + 7 as opus_val16, + 8 as opus_val16, + 16 as opus_val16, + 24 as opus_val16, + 36 as opus_val16, + 44 as opus_val16, + 50 as opus_val16, + 56 as opus_val16, + 62 as opus_val16, + 67 as opus_val16, + 72 as opus_val16, + 79 as opus_val16, + 88 as opus_val16, + 106 as opus_val16, + 134 as opus_val16, + ]; + static mut intensity_histeresis: [opus_val16; 21] = [ + 1 as opus_val16, + 1 as opus_val16, + 1 as opus_val16, + 1 as opus_val16, + 1 as opus_val16, + 1 as opus_val16, + 1 as opus_val16, + 2 as opus_val16, + 2 as opus_val16, + 2 as opus_val16, + 2 as opus_val16, + 2 as opus_val16, + 2 as opus_val16, + 2 as opus_val16, + 3 as opus_val16, + 3 as opus_val16, + 4 as opus_val16, + 5 as opus_val16, + 6 as opus_val16, + 8 as opus_val16, + 8 as opus_val16, + ]; + if LM != 0 { + dual_stereo = stereo_analysis(mode, X.as_mut_ptr(), LM, N); + } + (*st).intensity = hysteresis_decision( + (equiv_rate / 1000) as opus_val16, + intensity_thresholds.as_ptr(), + intensity_histeresis.as_ptr(), + 21, + (*st).intensity, + ); + (*st).intensity = if end + < (if start > (*st).intensity { + start + } else { + (*st).intensity + }) { + end + } else if start > (*st).intensity { + start + } else { + (*st).intensity + }; + } + alloc_trim = 5; + if tell + ((6) << BITRES) <= total_bits - total_boost { + if start > 0 || (*st).lfe != 0 { + (*st).stereo_saving = 0 as opus_val16; + alloc_trim = 5; + } else { + alloc_trim = alloc_trim_analysis( + mode, + X.as_mut_ptr(), + bandLogE.as_mut_ptr(), + end, + LM, + C, + N, + &mut (*st).analysis, + &mut (*st).stereo_saving, + tf_estimate, + (*st).intensity, + surround_trim, + equiv_rate, + (*st).arch, + ); + } + ec_enc_icdf(enc, alloc_trim, &trim_icdf, 7); + tell = ec_tell_frac(enc) as i32; + } + if vbr_rate > 0 { + let mut alpha: opus_val16 = 0.; + let mut delta: i32 = 0; + let mut target: i32 = 0; + let mut base_target: i32 = 0; + let mut min_allowed: i32 = 0; + let lm_diff: i32 = (*mode).maxLM - LM; + nbCompressedBytes = if nbCompressedBytes < 1275 >> 3 - LM { + nbCompressedBytes + } else { + 1275 >> 3 - LM + }; + if hybrid == 0 { + base_target = vbr_rate - ((40 * C + 20) << BITRES); + } else { + base_target = if 0 > vbr_rate - ((9 * C + 4) << 3) { + 0 + } else { + vbr_rate - ((9 * C + 4) << 3) + }; + } + if (*st).constrained_vbr != 0 { + base_target += (*st).vbr_offset >> lm_diff; + } + if hybrid == 0 { + target = compute_vbr( + mode, + &mut (*st).analysis, + base_target, + LM, + equiv_rate, + (*st).lastCodedBands, + C, + (*st).intensity, + (*st).constrained_vbr, + (*st).stereo_saving, + tot_boost, + tf_estimate, + pitch_change, + maxDepth, + (*st).lfe, + ((*st).energy_mask != NULL as *mut opus_val16) as i32, + surround_masking, + temporal_vbr, + ); + } else { + target = base_target; + if (*st).silk_info.offset < 100 { + target += (12) << BITRES >> 3 - LM; + } + if (*st).silk_info.offset > 100 { + target -= (18) << BITRES >> 3 - LM; + } + target += ((tf_estimate - 0.25f32) * ((50) << 3) as f32) as i32; + if tf_estimate > 0.7f32 { + target = if target > (50) << 3 { + target + } else { + (50) << 3 + }; + } + } + target = target + tell; + min_allowed = (tell + total_boost + ((1) << BITRES + 3) - 1 >> BITRES + 3) + 2; + if hybrid != 0 { + min_allowed = if min_allowed + > tell0_frac + ((37) << 3) + total_boost + ((1) << 3 + 3) - 1 >> 3 + 3 + { + min_allowed + } else { + tell0_frac + ((37) << 3) + total_boost + ((1) << 3 + 3) - 1 >> 3 + 3 + }; + } + nbAvailableBytes = target + ((1) << BITRES + 2) >> BITRES + 3; + nbAvailableBytes = if min_allowed > nbAvailableBytes { + min_allowed + } else { + nbAvailableBytes + }; + nbAvailableBytes = if nbCompressedBytes < nbAvailableBytes { + nbCompressedBytes + } else { + nbAvailableBytes + }; + delta = target - vbr_rate; + target = nbAvailableBytes << BITRES + 3; + if silence != 0 { + nbAvailableBytes = 2; + target = (2 * 8) << BITRES; + delta = 0; + } + if (*st).vbr_count < 970 { + (*st).vbr_count += 1; + alpha = 1.0f32 / ((*st).vbr_count + 20) as f32; + } else { + alpha = 0.001f32; + } + if (*st).constrained_vbr != 0 { + (*st).vbr_reservoir += target - vbr_rate; + } + if (*st).constrained_vbr != 0 { + (*st).vbr_drift += (alpha + * (delta * ((1) << lm_diff) - (*st).vbr_offset - (*st).vbr_drift) as f32) + as i32; + (*st).vbr_offset = -(*st).vbr_drift; + } + if (*st).constrained_vbr != 0 && (*st).vbr_reservoir < 0 { + let adjust: i32 = -(*st).vbr_reservoir / ((8) << BITRES); + nbAvailableBytes += if silence != 0 { 0 } else { adjust }; + (*st).vbr_reservoir = 0; + } + nbCompressedBytes = if nbCompressedBytes < nbAvailableBytes { + nbCompressedBytes + } else { + nbAvailableBytes + }; + ec_enc_shrink(enc, nbCompressedBytes as u32); + } + let vla_12 = nbEBands as usize; + let mut fine_quant: Vec = ::std::vec::from_elem(0, vla_12); + let vla_13 = nbEBands as usize; + let mut pulses: Vec = ::std::vec::from_elem(0, vla_13); + let vla_14 = nbEBands as usize; + let mut fine_priority: Vec = ::std::vec::from_elem(0, vla_14); + bits = (((nbCompressedBytes * 8) << BITRES) as u32) + .wrapping_sub(ec_tell_frac(enc)) + .wrapping_sub(1) as i32; + anti_collapse_rsv = if isTransient != 0 && LM >= 2 && bits >= (LM + 2) << BITRES { + (1) << BITRES + } else { + 0 + }; + bits -= anti_collapse_rsv; + signalBandwidth = end - 1; + if (*st).analysis.valid != 0 { + let mut min_bandwidth: i32 = 0; + if equiv_rate < 32000 * C { + min_bandwidth = 13; + } else if equiv_rate < 48000 * C { + min_bandwidth = 16; + } else if equiv_rate < 60000 * C { + min_bandwidth = 18; + } else if equiv_rate < 80000 * C { + min_bandwidth = 19; + } else { + min_bandwidth = 20; + } + signalBandwidth = if (*st).analysis.bandwidth > min_bandwidth { + (*st).analysis.bandwidth + } else { + min_bandwidth + }; + } + if (*st).lfe != 0 { + signalBandwidth = 1; + } + codedBands = clt_compute_allocation( + mode, + start, + end, + offsets.as_mut_ptr(), + cap.as_mut_ptr(), + alloc_trim, + &mut (*st).intensity, + &mut dual_stereo, + bits, + &mut balance, + pulses.as_mut_ptr(), + fine_quant.as_mut_ptr(), + fine_priority.as_mut_ptr(), + C, + LM, + enc, + 1, + (*st).lastCodedBands, + signalBandwidth, + ); + if (*st).lastCodedBands != 0 { + (*st).lastCodedBands = if ((*st).lastCodedBands + 1) + < (if (*st).lastCodedBands - 1 > codedBands { + (*st).lastCodedBands - 1 + } else { + codedBands + }) { + (*st).lastCodedBands + 1 + } else if (*st).lastCodedBands - 1 > codedBands { + (*st).lastCodedBands - 1 + } else { + codedBands + }; + } else { + (*st).lastCodedBands = codedBands; + } + quant_fine_energy( + mode, + start, + end, + oldBandE, + error.as_mut_ptr(), + fine_quant.as_mut_ptr(), + enc, + C, + ); + let vla_15 = (C * nbEBands) as usize; + let mut collapse_masks: Vec = ::std::vec::from_elem(0, vla_15); + quant_all_bands( + 1, + mode, + start, + end, + X.as_mut_ptr(), + if C == 2 { + X.as_mut_ptr().offset(N as isize) + } else { + NULL as *mut celt_norm + }, + collapse_masks.as_mut_ptr(), + bandE.as_mut_ptr(), + pulses.as_mut_ptr(), + shortBlocks, + (*st).spread_decision, + dual_stereo, + (*st).intensity, + tf_res.as_mut_ptr(), + nbCompressedBytes * ((8) << BITRES) - anti_collapse_rsv, + balance, + enc, + LM, + codedBands, + &mut (*st).rng, + (*st).complexity, + (*st).arch, + (*st).disable_inv, + ); + if anti_collapse_rsv > 0 { + anti_collapse_on = ((*st).consec_transient < 2) as i32; + ec_enc_bits(enc, anti_collapse_on as u32, 1); + } + quant_energy_finalise( + mode, + start, + end, + oldBandE, + error.as_mut_ptr(), + fine_quant.as_mut_ptr(), + fine_priority.as_mut_ptr(), + nbCompressedBytes * 8 - ec_tell(enc), + enc, + C, + ); + memset( + energyError as *mut core::ffi::c_void, + 0, + ((nbEBands * CC) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + c = 0; + loop { + i = start; + while i < end { + *energyError.offset((i + c * nbEBands) as isize) = if -0.5f32 + > (if 0.5f32 < *error.as_mut_ptr().offset((i + c * nbEBands) as isize) { + 0.5f32 + } else { + *error.as_mut_ptr().offset((i + c * nbEBands) as isize) + }) { + -0.5f32 + } else if 0.5f32 < *error.as_mut_ptr().offset((i + c * nbEBands) as isize) { + 0.5f32 + } else { + *error.as_mut_ptr().offset((i + c * nbEBands) as isize) + }; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + if silence != 0 { + i = 0; + while i < C * nbEBands { + *oldBandE.offset(i as isize) = -28.0f32; + i += 1; + } + } + (*st).prefilter_period = pitch_index; + (*st).prefilter_gain = gain1; + (*st).prefilter_tapset = prefilter_tapset; + if CC == 2 && C == 1 { + memcpy( + &mut *oldBandE.offset(nbEBands as isize) as *mut opus_val16 as *mut core::ffi::c_void, + oldBandE as *const core::ffi::c_void, + (nbEBands as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut *oldBandE.offset(nbEBands as isize) as *mut opus_val16) + .offset_from(oldBandE) as i64) as u64, + ), + ); + } + if isTransient == 0 { + memcpy( + oldLogE2 as *mut core::ffi::c_void, + oldLogE as *const core::ffi::c_void, + ((CC * nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * oldLogE2.offset_from(oldLogE) as i64) as u64), + ); + memcpy( + oldLogE as *mut core::ffi::c_void, + oldBandE as *const core::ffi::c_void, + ((CC * nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * oldLogE.offset_from(oldBandE) as i64) as u64), + ); + } else { + i = 0; + while i < CC * nbEBands { + *oldLogE.offset(i as isize) = + if *oldLogE.offset(i as isize) < *oldBandE.offset(i as isize) { + *oldLogE.offset(i as isize) + } else { + *oldBandE.offset(i as isize) + }; + i += 1; + } + } + c = 0; + loop { + i = 0; + while i < start { + *oldBandE.offset((c * nbEBands + i) as isize) = 0 as opus_val16; + let ref mut fresh5 = *oldLogE2.offset((c * nbEBands + i) as isize); + *fresh5 = -28.0f32; + *oldLogE.offset((c * nbEBands + i) as isize) = *fresh5; + i += 1; + } + i = end; + while i < nbEBands { + *oldBandE.offset((c * nbEBands + i) as isize) = 0 as opus_val16; + let ref mut fresh6 = *oldLogE2.offset((c * nbEBands + i) as isize); + *fresh6 = -28.0f32; + *oldLogE.offset((c * nbEBands + i) as isize) = *fresh6; + i += 1; + } + c += 1; + if !(c < CC) { + break; + } + } + if isTransient != 0 || transient_got_disabled != 0 { + (*st).consec_transient += 1; + } else { + (*st).consec_transient = 0; + } + (*st).rng = (*enc).rng; + ec_enc_done(enc); + if ec_get_error(enc) != 0 { + return OPUS_INTERNAL_ERROR; + } else { + return nbCompressedBytes; + }; +} +pub unsafe fn opus_custom_encoder_ctl_impl( + st: *mut OpusCustomEncoder, + request: i32, + args: VarArgs, +) -> i32 { + let current_block: u64; + let mut ap = args; + match request { + OPUS_SET_COMPLEXITY_REQUEST => { + let value: i32 = ap.arg::(); + if value < 0 || value > 10 { + current_block = 2472048668343472511; + } else { + (*st).complexity = value; + current_block = 10007731352114176167; + } + } + CELT_SET_START_BAND_REQUEST => { + let value_0: i32 = ap.arg::(); + if value_0 < 0 || value_0 >= (*(*st).mode).nbEBands { + current_block = 2472048668343472511; + } else { + (*st).start = value_0; + current_block = 10007731352114176167; + } + } + CELT_SET_END_BAND_REQUEST => { + let value_1: i32 = ap.arg::(); + if value_1 < 1 || value_1 > (*(*st).mode).nbEBands { + current_block = 2472048668343472511; + } else { + (*st).end = value_1; + current_block = 10007731352114176167; + } + } + CELT_SET_PREDICTION_REQUEST => { + let value_2: i32 = ap.arg::(); + if value_2 < 0 || value_2 > 2 { + current_block = 2472048668343472511; + } else { + (*st).disable_pf = (value_2 <= 1) as i32; + (*st).force_intra = (value_2 == 0) as i32; + current_block = 10007731352114176167; + } + } + OPUS_SET_PACKET_LOSS_PERC_REQUEST => { + let value_3: i32 = ap.arg::(); + if value_3 < 0 || value_3 > 100 { + current_block = 2472048668343472511; + } else { + (*st).loss_rate = value_3; + current_block = 10007731352114176167; + } + } + OPUS_SET_VBR_CONSTRAINT_REQUEST => { + let value_4: i32 = ap.arg::(); + (*st).constrained_vbr = value_4; + current_block = 10007731352114176167; + } + OPUS_SET_VBR_REQUEST => { + let value_5: i32 = ap.arg::(); + (*st).vbr = value_5; + current_block = 10007731352114176167; + } + OPUS_SET_BITRATE_REQUEST => { + let mut value_6: i32 = ap.arg::(); + if value_6 <= 500 && value_6 != OPUS_BITRATE_MAX { + current_block = 2472048668343472511; + } else { + value_6 = if value_6 < 260000 * (*st).channels { + value_6 + } else { + 260000 * (*st).channels + }; + (*st).bitrate = value_6; + current_block = 10007731352114176167; + } + } + CELT_SET_CHANNELS_REQUEST => { + let value_7: i32 = ap.arg::(); + if value_7 < 1 || value_7 > 2 { + current_block = 2472048668343472511; + } else { + (*st).stream_channels = value_7; + current_block = 10007731352114176167; + } + } + OPUS_SET_LSB_DEPTH_REQUEST => { + let value_8: i32 = ap.arg::(); + if value_8 < 8 || value_8 > 24 { + current_block = 2472048668343472511; + } else { + (*st).lsb_depth = value_8; + current_block = 10007731352114176167; + } + } + OPUS_GET_LSB_DEPTH_REQUEST => { + let value_9: &mut i32 = ap.arg::<&mut i32>(); + *value_9 = (*st).lsb_depth; + current_block = 10007731352114176167; + } + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_10: i32 = ap.arg::(); + if value_10 < 0 || value_10 > 1 { + current_block = 2472048668343472511; + } else { + (*st).disable_inv = value_10; + current_block = 10007731352114176167; + } + } + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_11: &mut i32 = ap.arg::<&mut i32>(); + *value_11 = (*st).disable_inv; + current_block = 10007731352114176167; + } + OPUS_RESET_STATE => { + let mut i: i32 = 0; + let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16; + let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16; + oldBandE = ((*st).in_mem) + .as_mut_ptr() + .offset(((*st).channels * ((*(*st).mode).overlap + COMBFILTER_MAXPERIOD)) as isize) + as *mut opus_val16; + oldLogE = oldBandE.offset(((*st).channels * (*(*st).mode).nbEBands) as isize); + oldLogE2 = oldLogE.offset(((*st).channels * (*(*st).mode).nbEBands) as isize); + memset( + &mut (*st).rng as *mut u32 as *mut i8 as *mut core::ffi::c_void, + 0, + ((opus_custom_encoder_get_size((*st).mode, (*st).channels) as i64 + - (&mut (*st).rng as *mut u32 as *mut i8).offset_from(st as *mut i8) as i64) + as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + i = 0; + while i < (*st).channels * (*(*st).mode).nbEBands { + let ref mut fresh7 = *oldLogE2.offset(i as isize); + *fresh7 = -28.0f32; + *oldLogE.offset(i as isize) = *fresh7; + i += 1; + } + (*st).vbr_offset = 0; + (*st).delayedIntra = 1 as opus_val32; + (*st).spread_decision = SPREAD_NORMAL; + (*st).tonal_average = 256; + (*st).hf_average = 0; + (*st).tapset_decision = 0; + current_block = 10007731352114176167; + } + CELT_SET_SIGNALLING_REQUEST => { + let value_12: i32 = ap.arg::(); + (*st).signalling = value_12; + current_block = 10007731352114176167; + } + CELT_SET_ANALYSIS_REQUEST => { + let info = ap.arg::<&mut AnalysisInfo>(); + memcpy( + &mut (*st).analysis as *mut AnalysisInfo as *mut core::ffi::c_void, + info as *mut AnalysisInfo as *const core::ffi::c_void, + (1_u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut (*st).analysis as *mut AnalysisInfo).offset_from(info) as i64) + as u64, + ), + ); + current_block = 10007731352114176167; + } + CELT_SET_SILK_INFO_REQUEST => { + let info_0 = ap.arg::<&mut SILKInfo>(); + memcpy( + &mut (*st).silk_info as *mut SILKInfo as *mut core::ffi::c_void, + info_0 as *mut SILKInfo as *const core::ffi::c_void, + (1_u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut (*st).silk_info as *mut SILKInfo).offset_from(info_0) as i64) + as u64, + ), + ); + current_block = 10007731352114176167; + } + CELT_GET_MODE_REQUEST => { + let value_13 = ap.arg::<&mut *const OpusCustomMode>(); + *value_13 = (*st).mode; + current_block = 10007731352114176167; + } + OPUS_GET_FINAL_RANGE_REQUEST => { + let value_14 = ap.arg::<&mut u32>(); + *value_14 = (*st).rng; + current_block = 10007731352114176167; + } + OPUS_SET_LFE_REQUEST => { + let value_15: i32 = ap.arg::(); + (*st).lfe = value_15; + current_block = 10007731352114176167; + } + OPUS_SET_ENERGY_MASK_REQUEST => { + let value_16: *mut opus_val16 = ap.arg::<*mut opus_val16>(); + (*st).energy_mask = value_16; + current_block = 10007731352114176167; + } + _ => return OPUS_UNIMPLEMENTED, + } + match current_block { + 10007731352114176167 => return OPUS_OK, + _ => return OPUS_BAD_ARG, + }; +} +#[macro_export] +macro_rules! opus_custom_encoder_ctl { + ($st:expr, $request:expr, $($arg:expr),*) => { + $crate::opus_custom_encoder_ctl_impl($st, $request, $crate::varargs!($($arg),*)) + }; + ($st:expr, $request:expr) => { + opus_custom_encoder_ctl!($st, $request,) + }; + ($st:expr, $request:expr, $($arg:expr),*,) => { + opus_custom_encoder_ctl!($st, $request, $($arg),*) + }; +} diff --git a/vendor/unsafe-libopus/src/celt/celt_lpc.rs b/vendor/unsafe-libopus/src/celt/celt_lpc.rs new file mode 100644 index 00000000..b8a47d26 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/celt_lpc.rs @@ -0,0 +1,236 @@ +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; +} +pub use self::arch_h::{opus_val16, opus_val32}; +use crate::celt::pitch::{celt_pitch_xcorr_c, xcorr_kernel_c}; +use crate::externs::memset; + +pub const LPC_ORDER: i32 = 24; + +pub unsafe fn _celt_lpc(mut _lpc: *mut opus_val16, ac: *const opus_val32, p: i32) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut r: opus_val32 = 0.; + let mut error: opus_val32 = *ac.offset(0 as isize); + let lpc: *mut f32 = _lpc; + memset( + lpc as *mut core::ffi::c_void, + 0, + (p as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + if *ac.offset(0 as isize) != 0 as f32 { + i = 0; + while i < p { + let mut rr: opus_val32 = 0 as opus_val32; + j = 0; + while j < i { + rr += *lpc.offset(j as isize) * *ac.offset((i - j) as isize); + j += 1; + } + rr += *ac.offset((i + 1) as isize); + r = -(rr / error); + *lpc.offset(i as isize) = r; + j = 0; + while j < i + 1 >> 1 { + let mut tmp1: opus_val32 = 0.; + let mut tmp2: opus_val32 = 0.; + tmp1 = *lpc.offset(j as isize); + tmp2 = *lpc.offset((i - 1 - j) as isize); + *lpc.offset(j as isize) = tmp1 + r * tmp2; + *lpc.offset((i - 1 - j) as isize) = tmp2 + r * tmp1; + j += 1; + } + error = error - r * r * error; + if error < 0.001f32 * *ac.offset(0 as isize) { + break; + } + i += 1; + } + } +} +pub unsafe fn celt_fir_c( + x: *const opus_val16, + num: *const opus_val16, + y: *mut opus_val16, + N: i32, + ord: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + assert!(x != y as *const opus_val16); + let vla = ord as usize; + let mut rnum: Vec = ::std::vec::from_elem(0., vla); + i = 0; + while i < ord { + *rnum.as_mut_ptr().offset(i as isize) = *num.offset((ord - i - 1) as isize); + i += 1; + } + i = 0; + while i < N - 3 { + let mut sum: [opus_val32; 4] = [0.; 4]; + sum[0 as usize] = *x.offset(i as isize); + sum[1 as usize] = *x.offset((i + 1) as isize); + sum[2 as usize] = *x.offset((i + 2) as isize); + sum[3 as usize] = *x.offset((i + 3) as isize); + xcorr_kernel_c( + rnum.as_mut_ptr(), + x.offset(i as isize).offset(-(ord as isize)), + sum.as_mut_ptr(), + ord, + ); + *y.offset(i as isize) = sum[0 as usize]; + *y.offset((i + 1) as isize) = sum[1 as usize]; + *y.offset((i + 2) as isize) = sum[2 as usize]; + *y.offset((i + 3) as isize) = sum[3 as usize]; + i += 4; + } + while i < N { + let mut sum_0: opus_val32 = *x.offset(i as isize); + j = 0; + while j < ord { + sum_0 = + sum_0 + *rnum.as_mut_ptr().offset(j as isize) * *x.offset((i + j - ord) as isize); + j += 1; + } + *y.offset(i as isize) = sum_0; + i += 1; + } +} +pub unsafe fn celt_iir( + mut _x: *const opus_val32, + den: *const opus_val16, + mut _y: *mut opus_val32, + N: i32, + ord: i32, + mem: *mut opus_val16, + _arch: i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + assert!(ord & 3 == 0); + let vla = ord as usize; + let mut rden: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = (N + ord) as usize; + let mut y: Vec = ::std::vec::from_elem(0., vla_0); + i = 0; + while i < ord { + *rden.as_mut_ptr().offset(i as isize) = *den.offset((ord - i - 1) as isize); + i += 1; + } + i = 0; + while i < ord { + *y.as_mut_ptr().offset(i as isize) = -*mem.offset((ord - i - 1) as isize); + i += 1; + } + while i < N + ord { + *y.as_mut_ptr().offset(i as isize) = 0 as opus_val16; + i += 1; + } + i = 0; + while i < N - 3 { + let mut sum: [opus_val32; 4] = [0.; 4]; + sum[0 as usize] = *_x.offset(i as isize); + sum[1 as usize] = *_x.offset((i + 1) as isize); + sum[2 as usize] = *_x.offset((i + 2) as isize); + sum[3 as usize] = *_x.offset((i + 3) as isize); + xcorr_kernel_c( + rden.as_mut_ptr(), + y.as_mut_ptr().offset(i as isize), + sum.as_mut_ptr(), + ord, + ); + *y.as_mut_ptr().offset((i + ord) as isize) = -sum[0 as usize]; + *_y.offset(i as isize) = sum[0 as usize]; + sum[1 as usize] = + sum[1 as usize] + *y.as_mut_ptr().offset((i + ord) as isize) * *den.offset(0 as isize); + *y.as_mut_ptr().offset((i + ord + 1) as isize) = -sum[1 as usize]; + *_y.offset((i + 1) as isize) = sum[1 as usize]; + sum[2 as usize] = sum[2 as usize] + + *y.as_mut_ptr().offset((i + ord + 1) as isize) * *den.offset(0 as isize); + sum[2 as usize] = + sum[2 as usize] + *y.as_mut_ptr().offset((i + ord) as isize) * *den.offset(1 as isize); + *y.as_mut_ptr().offset((i + ord + 2) as isize) = -sum[2 as usize]; + *_y.offset((i + 2) as isize) = sum[2 as usize]; + sum[3 as usize] = sum[3 as usize] + + *y.as_mut_ptr().offset((i + ord + 2) as isize) * *den.offset(0 as isize); + sum[3 as usize] = sum[3 as usize] + + *y.as_mut_ptr().offset((i + ord + 1) as isize) * *den.offset(1 as isize); + sum[3 as usize] = + sum[3 as usize] + *y.as_mut_ptr().offset((i + ord) as isize) * *den.offset(2 as isize); + *y.as_mut_ptr().offset((i + ord + 3) as isize) = -sum[3 as usize]; + *_y.offset((i + 3) as isize) = sum[3 as usize]; + i += 4; + } + while i < N { + let mut sum_0: opus_val32 = *_x.offset(i as isize); + j = 0; + while j < ord { + sum_0 -= + *rden.as_mut_ptr().offset(j as isize) * *y.as_mut_ptr().offset((i + j) as isize); + j += 1; + } + *y.as_mut_ptr().offset((i + ord) as isize) = sum_0; + *_y.offset(i as isize) = sum_0; + i += 1; + } + i = 0; + while i < ord { + *mem.offset(i as isize) = *_y.offset((N - i - 1) as isize); + i += 1; + } +} +pub unsafe fn _celt_autocorr( + x: *const opus_val16, + ac: *mut opus_val32, + window: *const opus_val16, + overlap: i32, + lag: i32, + n: i32, + arch: i32, +) -> i32 { + let mut d: opus_val32 = 0.; + let mut i: i32 = 0; + let mut k: i32 = 0; + let fastN: i32 = n - lag; + let mut shift: i32 = 0; + let mut xptr: *const opus_val16 = 0 as *const opus_val16; + let vla = n as usize; + let mut xx: Vec = ::std::vec::from_elem(0., vla); + assert!(n > 0); + assert!(overlap >= 0); + if overlap == 0 { + xptr = x; + } else { + i = 0; + while i < n { + *xx.as_mut_ptr().offset(i as isize) = *x.offset(i as isize); + i += 1; + } + i = 0; + while i < overlap { + *xx.as_mut_ptr().offset(i as isize) = + *x.offset(i as isize) * *window.offset(i as isize); + *xx.as_mut_ptr().offset((n - i - 1) as isize) = + *x.offset((n - i - 1) as isize) * *window.offset(i as isize); + i += 1; + } + xptr = xx.as_mut_ptr(); + } + shift = 0; + celt_pitch_xcorr_c(xptr, xptr, ac, fastN, lag + 1, arch); + k = 0; + while k <= lag { + i = k + fastN; + d = 0 as opus_val32; + while i < n { + d = d + *xptr.offset(i as isize) * *xptr.offset((i - k) as isize); + i += 1; + } + let ref mut fresh19 = *ac.offset(k as isize); + *fresh19 += d; + k += 1; + } + return shift; +} diff --git a/vendor/unsafe-libopus/src/celt/cwrs.rs b/vendor/unsafe-libopus/src/celt/cwrs.rs new file mode 100644 index 00000000..54422a49 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/cwrs.rs @@ -0,0 +1,457 @@ +pub mod arch_h { + pub type opus_val32 = f32; +} +pub use self::arch_h::opus_val32; +use crate::celt::entdec::{ec_dec, ec_dec_uint}; +use crate::celt::entenc::{ec_enc, ec_enc_uint}; + +/*Although derived separately, the pulse vector coding scheme is equivalent to + a Pyramid Vector Quantizer \cite{Fis86}. +Some additional notes about an early version appear at + https://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering + and the definitions of some terms have evolved since that was written. + +The conversion from a pulse vector to an integer index (encoding) and back + (decoding) is governed by two related functions, V(N,K) and U(N,K). + +V(N,K) = the number of combinations, with replacement, of N items, taken K + at a time, when a sign bit is added to each item taken at least once (i.e., + the number of N-dimensional unit pulse vectors with K pulses). +One way to compute this is via + V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1, + where choose() is the binomial function. +A table of values for N<10 and K<10 looks like: +V[10][10] = { + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + {1, 4, 8, 12, 16, 20, 24, 28, 32, 36}, + {1, 6, 18, 38, 66, 102, 146, 198, 258, 326}, + {1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992}, + {1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290}, + {1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436}, + {1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598}, + {1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688}, + {1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146} +}; + +U(N,K) = the number of such combinations wherein N-1 objects are taken at + most K-1 at a time. +This is given by + U(N,K) = sum(k=0...K-1,V(N-1,k)) + = K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0. +The latter expression also makes clear that U(N,K) is half the number of such + combinations wherein the first object is taken at least once. +Although it may not be clear from either of these definitions, U(N,K) is the + natural function to work with when enumerating the pulse vector codebooks, + not V(N,K). +U(N,K) is not well-defined for N=0, but with the extension + U(0,K) = K>0 ? 0 : 1, + the function becomes symmetric: U(N,K) = U(K,N), with a similar table: +U[10][10] = { + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 1, 3, 5, 7, 9, 11, 13, 15, 17}, + {0, 1, 5, 13, 25, 41, 61, 85, 113, 145}, + {0, 1, 7, 25, 63, 129, 231, 377, 575, 833}, + {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649}, + {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073}, + {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081}, + {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545}, + {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729} +}; + +With this extension, V(N,K) may be written in terms of U(N,K): + V(N,K) = U(N,K) + U(N,K+1) + for all N>=0, K>=0. +Thus U(N,K+1) represents the number of combinations where the first element + is positive or zero, and U(N,K) represents the number of combinations where + it is negative. +With a large enough table of U(N,K) values, we could write O(N) encoding + and O(min(N*log(K),N+K)) decoding routines, but such a table would be + prohibitively large for small embedded devices (K may be as large as 32767 + for small N, and N may be as large as 200). + +Both functions obey the same recurrence relation: + V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1), + U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1), + for all N>0, K>0, with different initial conditions at N=0 or K=0. +This allows us to construct a row of one of the tables above given the + previous row or the next row. +Thus we can derive O(NK) encoding and decoding routines with O(K) memory + using only addition and subtraction. + +When encoding, we build up from the U(2,K) row and work our way forwards. +When decoding, we need to start at the U(N,K) row and work our way backwards, + which requires a means of computing U(N,K). +U(N,K) may be computed from two previous values with the same N: + U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2) + for all N>1, and since U(N,K) is symmetric, a similar relation holds for two + previous values with the same K: + U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K) + for all K>1. +This allows us to construct an arbitrary row of the U(N,K) table by starting + with the first two values, which are constants. +This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K) + multiplications. +Similar relations can be derived for V(N,K), but are not used here. + +For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree + polynomial for fixed N. +The first few are + U(1,K) = 1, + U(2,K) = 2*K-1, + U(3,K) = (2*K-2)*K+1, + U(4,K) = (((4*K-6)*K+8)*K-3)/3, + U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3, + and + V(1,K) = 2, + V(2,K) = 4*K, + V(3,K) = 4*K*K+2, + V(4,K) = 8*(K*K+2)*K/3, + V(5,K) = ((4*K*K+20)*K*K+6)/3, + for all K>0. +This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for + small N (and indeed decoding is also O(N) for N<3). + +@ARTICLE{Fis86, + author="Thomas R. Fischer", + title="A Pyramid Vector Quantizer", + journal="IEEE Transactions on Information Theory", + volume="IT-32", + number=4, + pages="568--583", + month=Jul, + year=1986 +}*/ + +static PVQ_U_DATA2: [&[u32]; 15] = [ + /*N=0, K=0...176:*/ + &[ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + /*N=1, K=0...176:*/ + &[ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + ], + /*N=2, K=0...176:*/ + &[ + 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, + 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, + 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, + 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, + 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, + 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, + 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, + 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, + 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, + 347, 349, 351, + ], + /*N=3, K=0...176:*/ + &[ + 0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613, 685, + 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861, 1985, 2113, 2245, + 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785, 3961, 4141, 4325, 4513, 4705, + 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385, 6613, 6845, 7081, 7321, 7565, 7813, 8065, + 8321, 8581, 8845, 9113, 9385, 9661, 9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, + 12325, 12641, 12961, 13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, + 16745, 17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013, 21425, + 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765, 26221, 26681, 27145, + 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001, 31501, 32005, 32513, 33025, 33541, + 34061, 34585, 35113, 35645, 36181, 36721, 37265, 37813, 38365, 38921, 39481, 40045, 40613, + 41185, 41761, 42341, 42925, 43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, + 48985, 49613, 50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785, + 57461, 58141, 58825, 59513, 60205, 60901, 61601, + ], + /*N=4, K=0...176:*/ + &[ + 0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017, + 7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775, 30913, 34279, + 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153, 82239, 88641, 95367, 102425, + 109823, 117569, 125671, 134137, 142975, 152193, 161799, 171801, 182207, 193025, 204263, + 215929, 228031, 240577, 253575, 267033, 280959, 295361, 310247, 325625, 341503, 357889, + 374791, 392217, 410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951, + 597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609, 833511, 863097, + 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023, 1125369, 1161471, 1198337, + 1235975, 1274393, 1313599, 1353601, 1394407, 1436025, 1478463, 1521729, 1565831, 1610777, + 1656575, 1703233, 1750759, 1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, + 2163175, 2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751, 2699257, + 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583, 3244409, 3317311, 3391297, + 3466375, 3542553, 3619839, 3698241, 3777767, 3858425, 3940223, 4023169, 4107271, 4192537, + 4278975, 4366593, 4455399, 4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, + 5209575, 5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391, 6154617, + 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943, 7085049, 7207551, + ], + /*N=5, K=0..176:*/ + &[ + 0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, + 39041, 50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401, 330409, + 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241, 1061761, 1186369, 1321641, + 1468169, 1626561, 1797441, 1981449, 2179241, 2391489, 2618881, 2862121, 3121929, 3399041, + 3694209, 4008201, 4341801, 4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, + 7815849, 8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849, + 13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809, 20549801, 21675201, + 22846209, 24064041, 25329929, 26645121, 28010881, 29428489, 30899241, 32424449, 34005441, + 35643561, 37340169, 39096641, 40914369, 42794761, 44739241, 46749249, 48826241, 50971689, + 53187081, 55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609, 73612041, + 76526529, 79526721, 82614281, 85790889, 89058241, 92418049, 95872041, 99421961, 103069569, + 106816641, 110664969, 114616361, 118672641, 122835649, 127107241, 131489289, 135983681, + 140592321, 145317129, 150160041, 155123009, 160208001, 165417001, 170752009, 176215041, + 181808129, 187533321, 193392681, 199388289, 205522241, 211796649, 218213641, 224775361, + 231483969, 238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889, + 290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401, 351257409, + 360623041, 370174729, 379914921, 389846081, 399970689, 410291241, 420810249, 431530241, + 442453761, 453583369, 464921641, 476471169, 488234561, 500214441, 512413449, 524834241, + 537479489, 550351881, 563454121, 576788929, 590359041, 604167209, 618216201, 632508801, + ], + /*N=6, K=0...96:*/ + &[ + 0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, + 177045, 246047, 335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409, + 2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793, 11326283, 13115773, + 15124775, 17372905, 19880915, 22670725, 25765455, 29189457, 32968347, 37129037, 41699767, + 46710137, 52191139, 58175189, 64696159, 71789409, 79491819, 87841821, 96879431, 106646281, + 117185651, 128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185, + 235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647, 402823977, + 433078547, 465124549, 499040399, 534906769, 572806619, 612825229, 655050231, 699571641, + 746481891, 795875861, 847850911, 902506913, 959946283, 1020274013, 1083597703, 1150027593, + 1219676595, 1292660325, 1369097135, 1449108145, 1532817275, 1620351277, 1711839767, + 1807415257, 1907213187, 2011371957, 2120032959, + ], + /*N=7, K=0...54*/ + &[ + 0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, + 880685, 1303777, 1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233, + 19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013, 88043969, 106114625, + 127178701, 151620757, 179861305, 212358985, 249612805, 292164445, 340600625, 395555537, + 457713341, 527810725, 606639529, 695049433, 793950709, 904317037, 1027188385, 1163673953, + 1314955181, 1482288821, 1667010073, 1870535785, 2094367717, + ], + /*N=8, K=0...37*/ + &[ + 0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143, 433905, 795455, 1392065, + 2340495, 3800305, 5984767, 9173505, 13726991, 20103025, 28875327, 40754369, 56610575, + 77500017, 104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351, + 638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615, 2229491905, + ], + /*N=9, K=0...28:*/ + &[ + 0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417, 1256465, 2485825, 4673345, + 8405905, 14546705, 24331777, 39490049, 62390545, 96220561, 145198913, 214828609, 312193553, + 446304145, 628496897, 872893441, 1196924561, 1621925137, 2173806145, + ], + /*N=10, K=0...24:*/ + &[ + 0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563, 3317445, 7059735, + 14218905, 27298155, 50250765, 89129247, 152951073, 254831667, 413442773, 654862247, + 1014889769, 1541911931, 2300409629, 3375210671, + ], + /*N=11, K=0...19:*/ + &[ + 0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445, 8097453, 18474633, + 39753273, 81270333, 158819253, 298199265, 540279585, 948062325, 1616336765, + ], + /*N=12, K=0...18:*/ + &[ + 0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735, 18474633, 45046719, + 103274625, 224298231, 464387817, 921406335, 1759885185, 3248227095, + ], + /*N=13, K=0...16:*/ + &[ + 0, 1, 25, 313, 2625, 16641, 85305, 369305, 1392065, 4673345, 14218905, 39753273, 103274625, + 251595969, 579168825, 1267854873, 2653649025, + ], + /*N=14, K=0...14:*/ + &[ + 0, 1, 27, 365, 3303, 22569, 124515, 579125, 2340495, 8405905, 27298155, 81270333, + 224298231, 579168825, 1409933619, + ], +]; + +#[inline] +fn pvq_u(n: u32, k: u32) -> u32 { + // N = MIN(n, k) + // K = MAX(n, k) + let (n, k) = if n < k { (n, k) } else { (k, n) }; + // NOTE: this will cause panics if values are out of range + PVQ_U_DATA2[n as usize][k as usize] +} + +#[inline] +fn pvq_v(n: u32, k: u32) -> u32 { + pvq_u(n, k) + pvq_u(n, k + 1) +} + +#[cfg(test)] +mod test { + use std::fmt::Write; + + #[test] + fn pvq_u_table() { + let nk = [ + 0..=176, + 0..=176, + 0..=176, + 0..=176, + 0..=176, + 0..=176, + 0..=96, + 0..=54, + 0..=37, + 0..=28, + 0..=24, + 0..=19, + 0..=18, + 0..=16, + 0..=14, + ]; + + let mut table = String::new(); + for (n, kk) in nk.iter().enumerate() { + let n = n as u32; + for k in kk.clone() { + writeln!(table, "({}, {}) = {},", n, k, super::pvq_u(n, k)).unwrap(); + } + } + + insta::assert_snapshot!("pvq_u_table", table); + } +} + +unsafe fn icwrs(mut _n: i32, mut _y: *const i32) -> u32 { + let mut i: u32 = 0; + let mut j: u32 = 0; + let mut k: u32 = 0; + assert!(_n >= 2); + let n = _n as u32; + j = _n as u32 - 1; + i = (*_y.offset(j as isize) < 0) as u32; + k = (*_y.offset(j as isize)).abs() as u32; + loop { + j -= 1; + i = i.wrapping_add(pvq_u(n - j, k)); + k += (*_y.offset(j as isize)).abs() as u32; + if *_y.offset(j as isize) < 0 { + i = i.wrapping_add(pvq_u(n - j, k + 1)); + } + if !(j > 0) { + break; + } + } + return i; +} + +pub unsafe fn encode_pulses(mut _y: *const i32, mut _n: i32, mut _k: i32, mut _enc: *mut ec_enc) { + assert!(_k > 0); + ec_enc_uint(&mut *_enc, icwrs(_n, _y), pvq_v(_n as u32, _k as u32)); +} + +unsafe fn cwrsi(mut _n: i32, mut _k: i32, mut _i: u32, mut _y: *mut i32) -> opus_val32 { + let mut p: u32 = 0; + let mut s: i32 = 0; + let mut k0: i32 = 0; + let mut val: i16 = 0; + let mut yy: opus_val32 = 0 as opus_val32; + assert!(_k > 0); + assert!(_n > 1); + while _n > 2 { + let mut q: u32 = 0; + if _k >= _n { + let row = PVQ_U_DATA2[_n as usize]; + p = row[(_k + 1) as usize]; + s = -((_i >= p) as i32); + _i = (_i).wrapping_sub(p & s as u32); + k0 = _k; + q = row[_n as usize]; + if q > _i { + _k = _n; + loop { + _k -= 1; + p = PVQ_U_DATA2[_k as usize][_n as usize]; + if !(p > _i) { + break; + } + } + } else { + p = row[_k as usize]; + while p > _i { + _k -= 1; + p = row[_k as usize]; + } + } + _i = (_i).wrapping_sub(p); + val = (k0 - _k + s ^ s) as i16; + let fresh0 = _y; + _y = _y.offset(1); + *fresh0 = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + } else { + p = PVQ_U_DATA2[_k as usize][_n as usize]; + q = PVQ_U_DATA2[_k as usize + 1][_n as usize]; + if p <= _i && _i < q { + _i = _i.wrapping_sub(p); + let fresh1 = _y; + _y = _y.offset(1); + *fresh1 = 0; + } else { + s = -((_i >= q) as i32); + _i = _i.wrapping_sub(q & s as u32); + k0 = _k; + loop { + _k -= 1; + p = PVQ_U_DATA2[_k as usize][_n as usize]; + if !(p > _i) { + break; + } + } + _i = _i.wrapping_sub(p); + val = (k0 - _k + s ^ s) as i16; + let fresh2 = _y; + _y = _y.offset(1); + *fresh2 = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + } + } + _n -= 1; + } + p = (2 * _k + 1) as u32; + s = -((_i >= p) as i32); + _i = _i.wrapping_sub(p & s as u32); + k0 = _k; + _k = (_i.wrapping_add(1) >> 1) as i32; + if _k != 0 { + _i = _i.wrapping_sub((2 * _k - 1) as u32); + } + val = (k0 - _k + s ^ s) as i16; + let fresh3 = _y; + _y = _y.offset(1); + *fresh3 = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + s = -(_i as i32); + val = (_k + s ^ s) as i16; + *_y = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + return yy; +} +pub unsafe fn decode_pulses( + mut _y: *mut i32, + mut _n: i32, + mut _k: i32, + mut _dec: *mut ec_dec, +) -> opus_val32 { + return cwrsi( + _n, + _k, + ec_dec_uint(&mut *_dec, pvq_v(_n as u32, _k as u32)), + _y, + ); +} diff --git a/vendor/unsafe-libopus/src/celt/entcode.rs b/vendor/unsafe-libopus/src/celt/entcode.rs new file mode 100644 index 00000000..d0c463a2 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/entcode.rs @@ -0,0 +1,117 @@ +#![forbid(unsafe_code)] + +use crate::silk::macros::EC_CLZ0; + +pub const EC_SYM_BITS: i32 = 8; +pub const EC_CODE_BITS: i32 = 32; +pub const EC_SYM_MAX: u32 = (1_u32 << EC_SYM_BITS).wrapping_sub(1); +pub const EC_CODE_SHIFT: i32 = EC_CODE_BITS - EC_SYM_BITS - 1; +pub const EC_CODE_TOP: u32 = 1_u32 << (EC_CODE_BITS - 1); +pub const EC_CODE_BOT: u32 = EC_CODE_TOP >> EC_SYM_BITS; +pub const EC_CODE_EXTRA: i32 = (EC_CODE_BITS - 2) % EC_SYM_BITS + 1; + +pub type ec_window = u32; + +pub struct ec_ctx<'a> { + pub buf: &'a mut [u8], + pub storage: u32, + pub end_offs: u32, + pub end_window: ec_window, + pub nend_bits: i32, + pub nbits_total: i32, + pub offs: u32, + pub rng: u32, + pub val: u32, + pub ext: u32, + pub rem: i32, + pub error: i32, +} + +#[derive(Default, Copy, Clone)] +pub struct ec_ctx_saved { + pub storage: u32, + pub end_offs: u32, + pub end_window: ec_window, + pub nend_bits: i32, + pub nbits_total: i32, + pub offs: u32, + pub rng: u32, + pub val: u32, + pub ext: u32, + pub rem: i32, + pub error: i32, +} + +impl ec_ctx<'_> { + pub fn save(&self) -> ec_ctx_saved { + ec_ctx_saved { + storage: self.storage, + end_offs: self.end_offs, + end_window: self.end_window, + nend_bits: self.nend_bits, + nbits_total: self.nbits_total, + offs: self.offs, + rng: self.rng, + val: self.val, + ext: self.ext, + rem: self.rem, + error: self.error, + } + } + + /// NOTE: this function will summon dragons if you pass a `saved` value from a different `ec_ctx`. + /// + /// Also, you obviously don't want to pass a default `ec_ctx_saved` value. + pub fn restore(&mut self, saved: ec_ctx_saved) { + self.storage = saved.storage; + self.end_offs = saved.end_offs; + self.end_window = saved.end_window; + self.nend_bits = saved.nend_bits; + self.nbits_total = saved.nbits_total; + self.offs = saved.offs; + self.rng = saved.rng; + self.val = saved.val; + self.ext = saved.ext; + self.rem = saved.rem; + self.error = saved.error; + } +} + +pub const EC_UINT_BITS: i32 = 8; +pub const EC_WINDOW_SIZE: i32 = ::core::mem::size_of::() as i32 * 8; +pub const BITRES: i32 = 3; + +#[inline] +pub fn ec_get_error(this: &ec_ctx) -> i32 { + this.error +} + +#[inline] +pub fn ec_tell(this: &ec_ctx) -> i32 { + this.nbits_total - (EC_CLZ0 - this.rng.leading_zeros() as i32) +} + +#[inline] +pub fn celt_udiv(n: u32, d: u32) -> u32 { + n.wrapping_div(d) +} + +#[inline] +pub fn celt_sudiv(n: i32, d: i32) -> i32 { + n / d +} + +pub fn ec_tell_frac(this: &ec_ctx) -> u32 { + static correction: [u32; 8] = [35733, 38967, 42495, 46340, 50535, 55109, 60097, 65535]; + let mut nbits: u32 = 0; + let mut r: u32 = 0; + let mut l: i32 = 0; + let mut b: u32 = 0; + nbits = (this.nbits_total << BITRES) as u32; + l = EC_CLZ0 - (this.rng).leading_zeros() as i32; + r = this.rng >> (l - 16); + b = (r >> 12).wrapping_sub(8); + b = b.wrapping_add((r > correction[b as usize]) as i32 as u32); + l = ((l << 3) as u32).wrapping_add(b) as i32; + nbits.wrapping_sub(l as u32) +} diff --git a/vendor/unsafe-libopus/src/celt/entdec.rs b/vendor/unsafe-libopus/src/celt/entdec.rs new file mode 100644 index 00000000..1942bddc --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/entdec.rs @@ -0,0 +1,200 @@ +#![forbid(unsafe_code)] + +use crate::celt::entcode::{celt_udiv, ec_ctx, ec_window, EC_UINT_BITS, EC_WINDOW_SIZE}; +use crate::silk::macros::EC_CLZ0; + +pub type ec_dec<'a> = ec_ctx<'a>; + +use crate::celt::entcode::{ + EC_CODE_BITS, EC_CODE_BOT, EC_CODE_EXTRA, EC_CODE_TOP, EC_SYM_BITS, EC_SYM_MAX, +}; + +fn ec_read_byte(this: &mut ec_dec) -> i32 { + if this.offs < this.storage { + let res = this.buf[this.offs as usize] as i32; + + this.offs += 1; + + res + } else { + 0 + } +} + +fn ec_read_byte_from_end(this: &mut ec_dec) -> i32 { + if this.end_offs < this.storage { + this.end_offs += 1; + + this.buf[(this.storage - this.end_offs) as usize] as i32 + } else { + 0 + } +} + +fn ec_dec_normalize(this: &mut ec_dec) { + while this.rng <= EC_CODE_BOT { + let mut sym: i32 = 0; + this.nbits_total += EC_SYM_BITS; + this.rng <<= EC_SYM_BITS; + sym = this.rem; + this.rem = ec_read_byte(this); + sym = (sym << EC_SYM_BITS | this.rem) >> (EC_SYM_BITS - EC_CODE_EXTRA); + this.val = (this.val << EC_SYM_BITS).wrapping_add(EC_SYM_MAX & !sym as u32) + & EC_CODE_TOP.wrapping_sub(1); + } +} + +pub fn ec_dec_init(buf: &mut [u8]) -> ec_dec { + let mut this = ec_dec { + storage: buf.len() as u32, + buf, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: EC_CODE_BITS + 1 - (EC_CODE_BITS - EC_CODE_EXTRA) / EC_SYM_BITS * EC_SYM_BITS, + offs: 0, + rng: 1 << EC_CODE_EXTRA, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + + let rem = ec_read_byte(&mut this); + this.rem = rem; + this.val = (this.rng) + .wrapping_sub(1) + .wrapping_sub((this.rem >> (EC_SYM_BITS - EC_CODE_EXTRA)) as u32); + + ec_dec_normalize(&mut this); + + this +} + +pub fn ec_decode(this: &mut ec_dec, mut _ft: u32) -> u32 { + let mut s: u32 = 0; + this.ext = celt_udiv(this.rng, _ft); + s = (this.val).wrapping_div(this.ext); + + _ft.wrapping_sub(s.wrapping_add(1).wrapping_add( + _ft.wrapping_sub(s.wrapping_add(1)) & -((_ft < s.wrapping_add(1)) as i32) as u32, + )) +} + +pub fn ec_decode_bin(this: &mut ec_dec, mut _bits: u32) -> u32 { + let mut s: u32 = 0; + this.ext = this.rng >> _bits; + s = (this.val).wrapping_div(this.ext); + + (1_u32 << _bits).wrapping_sub(s.wrapping_add(1).wrapping_add( + (1_u32 << _bits).wrapping_sub(s.wrapping_add(1)) + & -((1_u32 << _bits < s.wrapping_add(1)) as i32) as u32, + )) +} + +pub fn ec_dec_update(mut _this: &mut ec_dec, mut _fl: u32, mut _fh: u32, mut _ft: u32) { + let mut s: u32 = 0; + s = (_this.ext).wrapping_mul(_ft.wrapping_sub(_fh)); + _this.val = _this.val.wrapping_sub(s); + _this.rng = if _fl > 0 { + (_this.ext).wrapping_mul(_fh.wrapping_sub(_fl)) + } else { + (_this.rng).wrapping_sub(s) + }; + ec_dec_normalize(_this); +} + +pub fn ec_dec_bit_logp(mut _this: &mut ec_dec, mut _logp: u32) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut ret: i32 = 0; + r = _this.rng; + d = _this.val; + s = r >> _logp; + ret = (d < s) as i32; + if ret == 0 { + _this.val = d.wrapping_sub(s); + } + _this.rng = if ret != 0 { s } else { r.wrapping_sub(s) }; + ec_dec_normalize(_this); + + ret +} + +pub fn ec_dec_icdf(mut _this: &mut ec_dec, icdf: &[u8], mut _ftb: u32) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut t: u32 = 0; + let mut ret: i32 = 0; + s = _this.rng; + d = _this.val; + r = s >> _ftb; + ret = -1; + loop { + t = s; + ret += 1; + s = r.wrapping_mul(icdf[ret as usize] as u32); + if !(d < s) { + break; + } + } + _this.val = d.wrapping_sub(s); + _this.rng = t.wrapping_sub(s); + ec_dec_normalize(_this); + + ret +} + +pub fn ec_dec_uint(mut _this: &mut ec_dec, mut _ft: u32) -> u32 { + let mut ft: u32 = 0; + let mut s: u32 = 0; + let mut ftb: i32 = 0; + assert!(_ft > 1); + _ft = _ft.wrapping_sub(1); + ftb = EC_CLZ0 - _ft.leading_zeros() as i32; + if ftb > EC_UINT_BITS { + let mut t: u32 = 0; + ftb -= EC_UINT_BITS; + ft = (_ft >> ftb).wrapping_add(1); + s = ec_decode(_this, ft); + ec_dec_update(_this, s, s.wrapping_add(1), ft); + t = s << ftb | ec_dec_bits(_this, ftb as u32); + if t <= _ft { + return t; + } + _this.error = 1; + _ft + } else { + _ft = _ft.wrapping_add(1); + s = ec_decode(_this, _ft); + ec_dec_update(_this, s, s.wrapping_add(1), _ft); + s + } +} + +pub fn ec_dec_bits(mut _this: &mut ec_dec, mut _bits: u32) -> u32 { + let mut window: ec_window = 0; + let mut available: i32 = 0; + let mut ret: u32 = 0; + window = _this.end_window; + available = _this.nend_bits; + if (available as u32) < _bits { + loop { + window |= (ec_read_byte_from_end(_this) as ec_window) << available; + available += EC_SYM_BITS; + if !(available <= EC_WINDOW_SIZE - EC_SYM_BITS) { + break; + } + } + } + ret = window & (1_u32 << _bits).wrapping_sub(1); + window >>= _bits; + available = (available as u32).wrapping_sub(_bits) as i32; + _this.end_window = window; + _this.nend_bits = available; + _this.nbits_total = (_this.nbits_total as u32).wrapping_add(_bits) as i32; + + ret +} diff --git a/vendor/unsafe-libopus/src/celt/entenc.rs b/vendor/unsafe-libopus/src/celt/entenc.rs new file mode 100644 index 00000000..807f3c1e --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/entenc.rs @@ -0,0 +1,302 @@ +#![forbid(unsafe_code)] + +use crate::celt::entcode::{celt_udiv, ec_ctx, ec_window, EC_UINT_BITS, EC_WINDOW_SIZE}; + +pub type ec_enc<'a> = ec_ctx<'a>; + +use crate::celt::entcode::{ + EC_CODE_BITS, EC_CODE_BOT, EC_CODE_SHIFT, EC_CODE_TOP, EC_SYM_BITS, EC_SYM_MAX, +}; + +use crate::silk::macros::EC_CLZ0; + +fn ec_write_byte(this: &mut ec_enc, value: u32) -> i32 { + #[cfg(feature = "ent-dump")] + eprintln!("ec_write_byte(0x{:x} @ 0x{:x})", value, this.offs); + if this.offs + this.end_offs >= this.storage { + return -1; + } + + this.buf[this.offs as usize] = value as u8; + this.offs += 1; + + 0 +} + +fn ec_write_byte_at_end(this: &mut ec_enc, value: u32) -> i32 { + #[cfg(feature = "ent-dump")] + eprintln!( + "ec_write_byte_at_end(0x{:x} @ 0x{:x})", + value, this.end_offs + ); + if this.offs + this.end_offs >= this.storage { + return -1; + } + + this.end_offs += 1; + this.buf[(this.storage - this.end_offs) as usize] = value as u8; + + 0 +} + +fn ec_enc_carry_out(this: &mut ec_enc, c: i32) { + if c as u32 != EC_SYM_MAX { + let mut carry: i32 = 0; + carry = c >> EC_SYM_BITS; + if this.rem >= 0 { + this.error |= ec_write_byte(this, (this.rem + carry) as u32); + } + if this.ext > 0 { + let mut sym: u32 = 0; + sym = EC_SYM_MAX.wrapping_add(carry as u32) & EC_SYM_MAX; + loop { + this.error |= ec_write_byte(this, sym); + this.ext -= 1; + if this.ext == 0 { + break; + } + } + } + this.rem = (c as u32 & EC_SYM_MAX) as i32; + } else { + this.ext += 1; + }; +} + +#[inline] +fn ec_enc_normalize(this: &mut ec_enc) { + while this.rng <= EC_CODE_BOT { + ec_enc_carry_out(this, (this.val >> EC_CODE_SHIFT) as i32); + this.val = this.val << EC_SYM_BITS & EC_CODE_TOP.wrapping_sub(1); + this.rng <<= EC_SYM_BITS; + this.nbits_total += EC_SYM_BITS; + } +} + +pub fn ec_enc_init(buf: &mut [u8]) -> ec_enc { + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_init()"); + ec_enc { + storage: buf.len() as u32, + buf, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: EC_CODE_BITS + 1, + offs: 0, + rng: EC_CODE_TOP, + val: 0, + ext: 0, + rem: -1, + error: 0, + } +} + +pub fn ec_encode(this: &mut ec_enc, mut _fl: u32, mut _fh: u32, mut _ft: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_encode({}, {}, {})", _fl, _fh, _ft); + let mut r: u32 = 0; + r = celt_udiv(this.rng, _ft); + if _fl > 0 { + this.val = this + .val + .wrapping_add((this.rng).wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fl)))); + this.rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + this.rng = this.rng.wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fh))); + } + ec_enc_normalize(this); +} + +pub fn ec_encode_bin(this: &mut ec_enc, mut _fl: u32, mut _fh: u32, mut _bits: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_encode_bin({}, {}, {})", _fl, _fh, _bits); + let mut r: u32 = 0; + r = this.rng >> _bits; + if _fl > 0 { + this.val = this.val.wrapping_add( + this.rng + .wrapping_sub(r.wrapping_mul((1_u32 << _bits).wrapping_sub(_fl))), + ); + this.rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + this.rng = this + .rng + .wrapping_sub(r.wrapping_mul((1_u32 << _bits).wrapping_sub(_fh))); + } + ec_enc_normalize(this); +} + +pub fn ec_enc_bit_logp(this: &mut ec_enc, mut _val: i32, mut _logp: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_bit_logp({}, {})", _val, _logp); + let mut r: u32 = 0; + let mut s: u32 = 0; + let mut l: u32 = 0; + r = this.rng; + l = this.val; + s = r >> _logp; + r = r.wrapping_sub(s); + if _val != 0 { + this.val = l.wrapping_add(r); + } + this.rng = if _val != 0 { s } else { r }; + ec_enc_normalize(this); +} + +pub fn ec_enc_icdf(this: &mut ec_enc, s: i32, icdf: &[u8], ftb: u32) { + // we do a sub-slice here because the C code doesn't have an idea about the icdf length (it doesn't need to) + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_icdf({}, {:?}, {})", s, &icdf[..=(s as usize)], ftb); + let mut r: u32 = 0; + r = this.rng >> ftb; + if s > 0 { + this.val = this.val.wrapping_add( + this.rng + .wrapping_sub(r.wrapping_mul(icdf[s as usize - 1] as u32)), + ); + this.rng = r.wrapping_mul((icdf[s as usize - 1] as i32 - icdf[s as usize] as i32) as u32); + } else { + this.rng = this + .rng + .wrapping_sub(r.wrapping_mul(icdf[s as usize] as u32)); + } + ec_enc_normalize(this); +} + +pub fn ec_enc_uint(mut _this: &mut ec_enc, mut _fl: u32, mut _ft: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_uint({}, {})", _fl, _ft); + let mut ft: u32 = 0; + let mut fl: u32 = 0; + let mut ftb: i32 = 0; + assert!(_ft > 1); + _ft = _ft.wrapping_sub(1); + ftb = EC_CLZ0 - _ft.leading_zeros() as i32; + if ftb > EC_UINT_BITS { + ftb -= EC_UINT_BITS; + ft = (_ft >> ftb).wrapping_add(1); + fl = _fl >> ftb; + ec_encode(_this, fl, fl.wrapping_add(1), ft); + ec_enc_bits(_this, _fl & (1_u32 << ftb).wrapping_sub(1), ftb as u32); + } else { + ec_encode(_this, _fl, _fl.wrapping_add(1), _ft.wrapping_add(1)); + }; +} + +pub fn ec_enc_bits(this: &mut ec_enc, mut _fl: u32, mut _bits: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_bits({}, {})", _fl, _bits); + let mut window: ec_window = 0; + let mut used: i32 = 0; + window = this.end_window; + used = this.nend_bits; + assert!(_bits > 0); + if (used as u32).wrapping_add(_bits) > EC_WINDOW_SIZE as u32 { + loop { + this.error |= ec_write_byte_at_end(this, window & EC_SYM_MAX); + window >>= EC_SYM_BITS; + used -= EC_SYM_BITS; + if !(used >= EC_SYM_BITS) { + break; + } + } + } + window |= _fl << used; + used = (used as u32).wrapping_add(_bits) as i32; + this.end_window = window; + this.nend_bits = used; + this.nbits_total = (this.nbits_total as u32).wrapping_add(_bits) as i32; +} + +pub fn ec_enc_patch_initial_bits(this: &mut ec_enc, mut _val: u32, mut _nbits: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_patch_initial_bits({}, {})", _val, _nbits); + let mut shift: i32 = 0; + let mut mask: u32 = 0; + assert!(_nbits <= 8); + shift = (EC_SYM_BITS as u32).wrapping_sub(_nbits) as i32; + mask = ((((1) << _nbits) - 1) << shift) as u32; + if this.offs > 0 { + this.buf[0] = (this.buf[0] as u32 & !mask | _val << shift) as u8; + } else if this.rem >= 0 { + this.rem = (this.rem as u32 & !mask | _val << shift) as i32; + } else if this.rng <= EC_CODE_TOP >> _nbits { + this.val = this.val & !(mask << EC_CODE_SHIFT) | _val << (EC_CODE_SHIFT + shift); + } else { + this.error = -1; + }; +} + +pub fn ec_enc_shrink(this: &mut ec_enc, new_size: u32) { + #[cfg(feature = "ent-dump")] + eprintln!("ec_enc_shrink({})", new_size); + assert!((this.offs).wrapping_add(this.end_offs) <= new_size); + + this.buf.copy_within( + (this.storage - this.end_offs) as usize..this.storage as usize, + (new_size - this.end_offs) as usize, + ); + this.storage = new_size; +} + +pub fn ec_enc_done(this: &mut ec_enc) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + let mut msk: u32 = 0; + let mut end: u32 = 0; + let mut l: i32 = 0; + /*We output the minimum number of bits that ensures that the symbols encoded + thus far will be decoded correctly regardless of the bits that follow.*/ + l = EC_CODE_BITS - (EC_CLZ0 - (this.rng).leading_zeros() as i32); + msk = EC_CODE_TOP.wrapping_sub(1) >> l; + end = (this.val).wrapping_add(msk) & !msk; + if end | msk >= (this.val).wrapping_add(this.rng) { + l += 1; + msk >>= 1; + end = (this.val).wrapping_add(msk) & !msk; + } + while l > 0 { + ec_enc_carry_out(this, (end >> EC_CODE_SHIFT) as i32); + end = end << EC_SYM_BITS & EC_CODE_TOP.wrapping_sub(1); + l -= EC_SYM_BITS; + } + /*If we have a buffered byte flush it into the output buffer.*/ + if this.rem >= 0 || this.ext > 0 { + ec_enc_carry_out(this, 0); + } + /*If we have buffered extra bits, flush them as well.*/ + window = this.end_window; + used = this.nend_bits; + while used >= EC_SYM_BITS { + this.error |= ec_write_byte_at_end(this, window & EC_SYM_MAX); + window >>= EC_SYM_BITS; + used -= EC_SYM_BITS; + } + /*Clear any excess space and add any remaining extra bits to the last byte.*/ + if this.error == 0 { + this.buf[this.offs as usize..(this.storage - this.end_offs) as usize].fill(0); + if used > 0 { + /*If there's no range coder data at all, give up.*/ + if this.end_offs >= this.storage { + this.error = -1; + } else { + /*If we've busted, don't add too many extra bits to the last byte; it + would corrupt the range coder data, and that's more important.*/ + l = -l; + if (this.offs).wrapping_add(this.end_offs) >= this.storage && l < used { + window &= (((1) << l) - 1) as u32; + this.error = -1; + } + let fresh1 = &mut this.buf[(this.storage - this.end_offs - 1) as usize]; + *fresh1 = (*fresh1 as i32 | window as u8 as i32) as u8; + } + } + } + + #[cfg(feature = "ent-dump")] + eprintln!( + "ec_enc_done(): {}", + hex::encode(&this.buf[..this.storage as usize]) + ); +} diff --git a/vendor/unsafe-libopus/src/celt/float_cast.rs b/vendor/unsafe-libopus/src/celt/float_cast.rs new file mode 100644 index 00000000..6cafa3d3 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/float_cast.rs @@ -0,0 +1,13 @@ +pub const CELT_SIG_SCALE: f32 = 32768.0f32; + +#[inline] +pub fn FLOAT2INT16(x: f32) -> i16 { + let x = x * CELT_SIG_SCALE; + let x = x.max(-32768.0); + let x = x.min(32767.0); + float2int(x) as i16 +} +#[inline] +pub fn float2int(x: f32) -> i32 { + (x + 0.5).floor() as i32 +} diff --git a/vendor/unsafe-libopus/src/celt/kiss_fft.rs b/vendor/unsafe-libopus/src/celt/kiss_fft.rs new file mode 100644 index 00000000..c1998c4b --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/kiss_fft.rs @@ -0,0 +1,251 @@ +#![forbid(unsafe_code)] + +use num_traits::Zero; +pub type kiss_fft_cpx = num_complex::Complex32; +pub type kiss_twiddle_cpx = num_complex::Complex32; + +#[derive(Copy, Clone)] +pub struct kiss_fft_state<'a> { + pub nfft: usize, + pub scale: f32, + pub shift: i32, + pub factors: [(i32, i32); 8], + pub bitrev: &'a [i16], + pub twiddles: &'a [kiss_twiddle_cpx; 480], +} + +fn kf_bfly2(Fout: &mut [kiss_fft_cpx], m: i32, N: i32) { + let tw: f32 = std::f32::consts::FRAC_1_SQRT_2; + /* We know that m==4 here because the radix-2 is just after a radix-4 */ + assert_eq!(m, 4); + assert_eq!(Fout.len(), N as usize * 8); + for chunk in Fout.chunks_exact_mut(8) { + let (Fout, Fout2) = chunk.split_at_mut(4); + + let t = Fout2[0]; + Fout2[0] = Fout[0] - t; + Fout[0] += t; + + let t = kiss_fft_cpx::new( + (Fout2[1].re + Fout2[1].im) * tw, + (Fout2[1].im - Fout2[1].re) * tw, + ); + Fout2[1] = Fout[1] - t; + Fout[1] += t; + + let t = kiss_fft_cpx::new(Fout2[2].im, -Fout2[2].re); + Fout2[2] = Fout[2] - t; + Fout[2] += t; + + let t = kiss_fft_cpx::new( + (Fout2[3].im - Fout2[3].re) * tw, + -(Fout2[3].im + Fout2[3].re) * tw, + ); + Fout2[3] = Fout[3] - t; + Fout[3] += t; + } +} +fn kf_bfly4( + Fout: &mut [kiss_fft_cpx], + fstride: usize, + st: &kiss_fft_state, + m: i32, + N: i32, + mm: i32, +) { + if m == 1 { + /* Degenerate case where all the twiddles are 1. */ + assert_eq!(Fout.len(), N as usize * 4); + for chunk in Fout.chunks_exact_mut(4) { + let scratch0 = chunk[0] - chunk[2]; + chunk[0] += chunk[2]; + let scratch1 = chunk[1] + chunk[3]; + chunk[2] = chunk[0] - scratch1; + chunk[0] += scratch1; + let scratch1 = chunk[1] - chunk[3]; + + chunk[1].re = scratch0.re + scratch1.im; + chunk[1].im = scratch0.im - scratch1.re; + chunk[3].re = scratch0.re - scratch1.im; + chunk[3].im = scratch0.im + scratch1.re; + } + } else { + let mut scratch: [kiss_fft_cpx; 6] = [kiss_fft_cpx::zero(); 6]; + let m = m as usize; + let m2 = 2 * m; + let m3 = 3 * m; + + for i in 0..N { + let mut chunk = &mut Fout[(i * mm) as usize..][..4 * m]; + let mut tw1 = st.twiddles.as_slice(); + let mut tw2 = tw1; + let mut tw3 = tw2; + /* m is guaranteed to be a multiple of 4. */ + for _ in 0..m { + scratch[0] = chunk[m] * tw1[0]; + scratch[1] = chunk[m2] * tw2[0]; + scratch[2] = chunk[m3] * tw3[0]; + + scratch[5] = chunk[0] - scratch[1]; + chunk[0] += scratch[1]; + scratch[3] = scratch[0] + scratch[2]; + scratch[4] = scratch[0] - scratch[2]; + chunk[m2] = chunk[0] - scratch[3]; + tw1 = &tw1[fstride..]; + tw2 = &tw2[fstride * 2..]; + tw3 = &tw3[fstride * 3..]; + chunk[0] += scratch[3]; + + chunk[m].re = scratch[5].re + scratch[4].im; + chunk[m].im = scratch[5].im - scratch[4].re; + chunk[m3].re = scratch[5].re - scratch[4].im; + chunk[m3].im = scratch[5].im + scratch[4].re; + chunk = &mut chunk[1..]; + } + } + }; +} +fn kf_bfly3( + Fout: &mut [kiss_fft_cpx], + fstride: usize, + st: &kiss_fft_state, + m: i32, + N: i32, + mm: i32, +) { + let m = m as usize; + let m2 = 2 * m; + let mut scratch: [kiss_fft_cpx; 5] = [kiss_fft_cpx::zero(); 5]; + let epi3 = st.twiddles[fstride * m]; + for i in 0..N { + let mut chunk = &mut Fout[(i * mm) as usize..][..3 * m]; + let mut tw2 = st.twiddles.as_slice(); + let mut tw1 = tw2; + /* For non-custom modes, m is guaranteed to be a multiple of 4. */ + for _ in 0..m { + scratch[1] = chunk[m] * tw1[0]; + scratch[2] = chunk[m2] * tw2[0]; + + scratch[3] = scratch[1] + scratch[2]; + scratch[0] = scratch[1] - scratch[2]; + tw1 = &tw1[fstride..]; + tw2 = &tw2[fstride * 2..]; + + chunk[m] = chunk[0] - scratch[3] * 0.5f32; + + scratch[0] *= epi3.im; + + chunk[0] += scratch[3]; + + chunk[m2].re = chunk[m].re + scratch[0].im; + chunk[m2].im = chunk[m].im - scratch[0].re; + + chunk[m].re -= scratch[0].im; + chunk[m].im += scratch[0].re; + + chunk = &mut chunk[1..]; + } + } +} +fn kf_bfly5( + Fout: &mut [kiss_fft_cpx], + fstride: usize, + st: &kiss_fft_state, + m: i32, + N: i32, + mm: i32, +) { + let mut scratch: [kiss_fft_cpx; 13] = [kiss_fft_cpx::zero(); 13]; + let ya = st.twiddles[fstride * m as usize]; + let yb = st.twiddles[fstride * m as usize * 2]; + let tw = st.twiddles.as_slice(); + let m = m as usize; + for i in 0..N { + let chunk = &mut Fout[(i * mm) as usize..][..5 * m]; + let (mut chunk0, chunk) = chunk.split_at_mut(m); + let (mut chunk1, chunk) = chunk.split_at_mut(m); + let (mut chunk2, chunk) = chunk.split_at_mut(m); + let (mut chunk3, mut chunk4) = chunk.split_at_mut(m); + + /* For non-custom modes, m is guaranteed to be a multiple of 4. */ + for u in 0..m { + scratch[0] = chunk0[0]; + + scratch[1] = chunk1[0] * tw[1 * u * fstride]; + scratch[2] = chunk2[0] * tw[2 * u * fstride]; + scratch[3] = chunk3[0] * tw[3 * u * fstride]; + scratch[4] = chunk4[0] * tw[4 * u * fstride]; + + scratch[7] = scratch[1] + scratch[4]; + scratch[10] = scratch[1] - scratch[4]; + scratch[8] = scratch[2] + scratch[3]; + scratch[9] = scratch[2] - scratch[3]; + + chunk0[0] += scratch[7] + scratch[8]; + + scratch[5].re = scratch[0].re + (scratch[7].re * ya.re + scratch[8].re * yb.re); + scratch[5].im = scratch[0].im + (scratch[7].im * ya.re + scratch[8].im * yb.re); + + scratch[6].re = scratch[10].im * ya.im + scratch[9].im * yb.im; + scratch[6].im = -(scratch[10].re * ya.im + scratch[9].re * yb.im); + + chunk1[0] = scratch[5] - scratch[6]; + chunk4[0] = scratch[5] + scratch[6]; + + scratch[11].re = scratch[0].re + (scratch[7].re * yb.re + scratch[8].re * ya.re); + scratch[11].im = scratch[0].im + (scratch[7].im * yb.re + scratch[8].im * ya.re); + scratch[12].re = scratch[9].im * ya.im - scratch[10].im * yb.im; + scratch[12].im = scratch[10].re * yb.im - scratch[9].re * ya.im; + + chunk2[0] = scratch[11] + scratch[12]; + chunk3[0] = scratch[11] - scratch[12]; + + chunk0 = &mut chunk0[1..]; + chunk1 = &mut chunk1[1..]; + chunk2 = &mut chunk2[1..]; + chunk3 = &mut chunk3[1..]; + chunk4 = &mut chunk4[1..]; + } + } +} + +pub fn opus_fft_impl(st: &kiss_fft_state, fout: &mut [kiss_fft_cpx]) { + let shift = st.shift.max(0); + + let mut fstride: [i32; 8] = [0; 8]; + fstride[0] = 1; + + let mut L = 0_usize; + loop { + let (p, m) = st.factors[L]; + fstride[L + 1] = fstride[L] * p; + L += 1; + if m == 1 { + break; + } + } + + let mut m = st.factors[L - 1].1; + for i in (0..L).rev() { + let m2 = if i > 0 { st.factors[i - 1].1 } else { 1 }; + match st.factors[i].0 { + 2 => kf_bfly2(fout, m, fstride[i]), + 4 => kf_bfly4(fout, (fstride[i] << shift) as usize, st, m, fstride[i], m2), + 3 => kf_bfly3(fout, (fstride[i] << shift) as usize, st, m, fstride[i], m2), + 5 => kf_bfly5(fout, (fstride[i] << shift) as usize, st, m, fstride[i], m2), + _ => {} + } + m = m2; + } +} + +pub fn opus_fft_c(st: &kiss_fft_state, fin: &[kiss_fft_cpx], fout: &mut [kiss_fft_cpx]) { + let mut scale: f32 = 0.; + scale = st.scale; + assert_eq!(fin.len(), st.nfft); + assert_eq!(fout.len(), st.nfft); + for (&x, &i) in fin.iter().zip(st.bitrev) { + fout[i as usize] = scale * x; + } + opus_fft_impl(st, fout); +} diff --git a/vendor/unsafe-libopus/src/celt/laplace.rs b/vendor/unsafe-libopus/src/celt/laplace.rs new file mode 100644 index 00000000..11473497 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/laplace.rs @@ -0,0 +1,107 @@ +use crate::celt::entdec::{ec_dec, ec_dec_update, ec_decode_bin}; +use crate::celt::entenc::{ec_enc, ec_encode_bin}; + +pub const LAPLACE_LOG_MINP: i32 = 0; +pub const LAPLACE_MINP: i32 = (1) << LAPLACE_LOG_MINP; +pub const LAPLACE_NMIN: i32 = 16; +unsafe fn ec_laplace_get_freq1(fs0: u32, decay: i32) -> u32 { + let mut ft: u32 = 0; + ft = ((32768 - LAPLACE_MINP * (2 * LAPLACE_NMIN)) as u32).wrapping_sub(fs0); + return ft.wrapping_mul((16384 - decay) as u32) >> 15; +} +pub unsafe fn ec_laplace_encode(enc: &mut ec_enc, value: *mut i32, mut fs: u32, decay: i32) { + let mut fl: u32 = 0; + let mut val: i32 = *value; + fl = 0; + if val != 0 { + let mut s: i32 = 0; + let mut i: i32 = 0; + s = -((val < 0) as i32); + val = val + s ^ s; + fl = fs; + fs = ec_laplace_get_freq1(fs, decay); + i = 1; + while fs > 0 && i < val { + fs = fs.wrapping_mul(2); + fl = fl.wrapping_add(fs.wrapping_add((2 * LAPLACE_MINP) as u32)); + fs = fs.wrapping_mul(decay as u32) >> 15; + i += 1; + } + if fs == 0 { + let mut di: i32 = 0; + let mut ndi_max: i32 = 0; + ndi_max = (32768_u32 + .wrapping_sub(fl) + .wrapping_add(LAPLACE_MINP as u32) + .wrapping_sub(1) + >> LAPLACE_LOG_MINP) as i32; + ndi_max = ndi_max - s >> 1; + di = if val - i < ndi_max - 1 { + val - i + } else { + ndi_max - 1 + }; + fl = fl.wrapping_add(((2 * di + 1 + s) * LAPLACE_MINP) as u32); + fs = if (((1) << 0) as u32) < 32768_u32.wrapping_sub(fl) { + ((1) << 0) as u32 + } else { + 32768_u32.wrapping_sub(fl) + }; + *value = i + di + s ^ s; + } else { + fs = fs.wrapping_add(LAPLACE_MINP as u32); + fl = fl.wrapping_add(fs & !s as u32); + } + assert!(fl.wrapping_add(fs) <= 32768); + assert!(fs > 0); + } + ec_encode_bin(enc, fl, fl.wrapping_add(fs), 15); +} +pub unsafe fn ec_laplace_decode(dec: &mut ec_dec, mut fs: u32, decay: i32) -> i32 { + let mut val: i32 = 0; + let mut fl: u32 = 0; + let mut fm: u32 = 0; + fm = ec_decode_bin(dec, 15); + fl = 0; + if fm >= fs { + val += 1; + fl = fs; + fs = (ec_laplace_get_freq1(fs, decay)).wrapping_add(LAPLACE_MINP as u32); + while fs > LAPLACE_MINP as u32 && fm >= fl.wrapping_add(2_u32.wrapping_mul(fs)) { + fs = fs.wrapping_mul(2); + fl = fl.wrapping_add(fs); + fs = fs + .wrapping_sub((2 * LAPLACE_MINP) as u32) + .wrapping_mul(decay as u32) + >> 15; + fs = fs.wrapping_add(LAPLACE_MINP as u32); + val += 1; + } + if fs <= LAPLACE_MINP as u32 { + let mut di: i32 = 0; + di = (fm.wrapping_sub(fl) >> LAPLACE_LOG_MINP + 1) as i32; + val += di; + fl = fl.wrapping_add((2 * di * LAPLACE_MINP) as u32); + } + if fm < fl.wrapping_add(fs) { + val = -val; + } else { + fl = fl.wrapping_add(fs); + } + } + assert!(fl < 32768); + assert!(fs > 0); + assert!(fl <= fm); + assert!(fm < fl.wrapping_add(fs).min(32768)); + ec_dec_update( + dec, + fl, + if fl.wrapping_add(fs) < 32768 { + fl.wrapping_add(fs) + } else { + 32768 + }, + 32768, + ); + return val; +} diff --git a/vendor/unsafe-libopus/src/celt/mathops.rs b/vendor/unsafe-libopus/src/celt/mathops.rs new file mode 100644 index 00000000..9e861007 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/mathops.rs @@ -0,0 +1,119 @@ +use crate::silk::macros::EC_CLZ0; + +use std::f32::consts::PI; + +pub const cA: f32 = 0.43157974f32; +pub const cB: f32 = 0.67848403f32; +pub const cC: f32 = 0.08595542f32; +pub const cE: f32 = PI / 2 as f32; + +pub unsafe fn isqrt32(mut _val: u32) -> u32 { + let mut b: u32 = 0; + let mut g: u32 = 0; + let mut bshift: i32 = 0; + g = 0; + bshift = EC_CLZ0 - _val.leading_zeros() as i32 - 1 >> 1; + b = (1 as u32) << bshift; + loop { + let mut t: u32 = 0; + t = (g << 1).wrapping_add(b) << bshift; + if t <= _val { + g = g.wrapping_add(b); + _val = (_val as u32).wrapping_sub(t) as u32 as u32; + } + b >>= 1; + bshift -= 1; + if !(bshift >= 0) { + break; + } + } + return g; +} + +#[inline] +pub unsafe fn fast_atan2f(y: f32, x: f32) -> f32 { + let mut x2: f32 = 0.; + let mut y2: f32 = 0.; + x2 = x * x; + y2 = y * y; + if x2 + y2 < 1e-18f32 { + return 0 as f32; + } + if x2 < y2 { + let den: f32 = (y2 + cB * x2) * (y2 + cC * x2); + return -x * y * (y2 + cA * x2) / den + (if y < 0 as f32 { -cE } else { cE }); + } else { + let den_0: f32 = (x2 + cB * y2) * (x2 + cC * y2); + return x * y * (x2 + cA * y2) / den_0 + (if y < 0 as f32 { -cE } else { cE }) + - (if x * y < 0 as f32 { -cE } else { cE }); + }; +} + +pub type opus_val16 = f32; +pub type opus_val32 = f32; + +#[inline] +pub unsafe fn celt_maxabs16(x: *const opus_val16, len: i32) -> opus_val32 { + let mut i: i32 = 0; + let mut maxval: opus_val16 = 0 as opus_val16; + let mut minval: opus_val16 = 0 as opus_val16; + i = 0; + while i < len { + maxval = if maxval > *x.offset(i as isize) { + maxval + } else { + *x.offset(i as isize) + }; + minval = if minval < *x.offset(i as isize) { + minval + } else { + *x.offset(i as isize) + }; + i += 1; + } + return if maxval > -minval { maxval } else { -minval }; +} + +// the functions below are analogous to the macros defined in mathops.h header. +// importantly, some of them do conversion to f64 before doing the operation, to make sure the results will match the original implementation. +// it uses the f64 math functions because they are more portable, so we are stuck with them too if we want reproducible bitcode. + +#[inline] +pub fn celt_sqrt(x: f32) -> f32 { + (x as f64).sqrt() as f32 +} + +#[inline] +pub fn celt_rsqrt(x: f32) -> f32 { + 1.0f32 / celt_sqrt(x) +} + +#[inline] +pub fn celt_rsqrt_norm(x: f32) -> f32 { + celt_rsqrt(x) +} + +#[inline] +pub fn celt_cos_norm(x: f32) -> f32 { + ((0.5f32 * PI * x) as f64).cos() as f32 +} + +#[inline] +pub fn celt_log(x: f32) -> f32 { + (x as f64).ln() as f32 +} + +#[inline] +pub fn celt_log10(x: f32) -> f32 { + (x as f64).log10() as f32 +} + +#[inline] +pub fn celt_log2(f: f32) -> f32 { + (std::f64::consts::LOG2_E * (f as f64).ln()) as f32 +} + +#[inline] +pub fn celt_exp2(f: f32) -> f32 { + (std::f64::consts::LN_2 * f as f64).exp() as f32 +} diff --git a/vendor/unsafe-libopus/src/celt/mdct.rs b/vendor/unsafe-libopus/src/celt/mdct.rs new file mode 100644 index 00000000..45e7d186 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/mdct.rs @@ -0,0 +1,238 @@ +use crate::celt::kiss_fft::{kiss_fft_cpx, kiss_fft_state, opus_fft_impl}; +use num_traits::Zero; + +pub mod arch_h { + pub type opus_val16 = f32; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct mdct_lookup<'a> { + pub n: i32, + pub maxshift: i32, + pub kfft: [&'a kiss_fft_state<'a>; 4], + pub trig: &'a [&'a [f32]; 4], +} +pub use self::arch_h::opus_val16; + +pub unsafe fn clt_mdct_forward_c( + l: &mdct_lookup, + in_0: *mut f32, + out: *mut f32, + window: *const opus_val16, + overlap: i32, + shift: i32, + stride: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut N2: i32 = 0; + let mut N4: i32 = 0; + let st: &kiss_fft_state = l.kfft[shift as usize]; + let mut scale: opus_val16 = 0.; + scale = st.scale; + let trig = l.trig[shift as usize]; + N = l.n >> shift; + N2 = N >> 1; + N4 = N >> 2; + let vla = N2 as usize; + let mut f: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = N4 as usize; + let mut f2: Vec = ::std::vec::from_elem(kiss_fft_cpx::zero(), vla_0); + let mut xp1: *const f32 = in_0.offset((overlap >> 1) as isize); + let mut xp2: *const f32 = in_0 + .offset(N2 as isize) + .offset(-(1 as isize)) + .offset((overlap >> 1) as isize); + let mut yp: *mut f32 = f.as_mut_ptr(); + let mut wp1: *const opus_val16 = window.offset((overlap >> 1) as isize); + let mut wp2: *const opus_val16 = window.offset((overlap >> 1) as isize).offset(-(1 as isize)); + i = 0; + while i < overlap + 3 >> 2 { + let fresh0 = yp; + yp = yp.offset(1); + *fresh0 = *wp2 * *xp1.offset(N2 as isize) + *wp1 * *xp2; + let fresh1 = yp; + yp = yp.offset(1); + *fresh1 = *wp1 * *xp1 - *wp2 * *xp2.offset(-N2 as isize); + xp1 = xp1.offset(2 as isize); + xp2 = xp2.offset(-(2 as isize)); + wp1 = wp1.offset(2 as isize); + wp2 = wp2.offset(-(2 as isize)); + i += 1; + } + wp1 = window; + wp2 = window.offset(overlap as isize).offset(-(1 as isize)); + while i < N4 - (overlap + 3 >> 2) { + let fresh2 = yp; + yp = yp.offset(1); + *fresh2 = *xp2; + let fresh3 = yp; + yp = yp.offset(1); + *fresh3 = *xp1; + xp1 = xp1.offset(2 as isize); + xp2 = xp2.offset(-(2 as isize)); + i += 1; + } + while i < N4 { + let fresh4 = yp; + yp = yp.offset(1); + *fresh4 = -(*wp1 * *xp1.offset(-N2 as isize)) + *wp2 * *xp2; + let fresh5 = yp; + yp = yp.offset(1); + *fresh5 = *wp2 * *xp1 + *wp1 * *xp2.offset(N2 as isize); + xp1 = xp1.offset(2 as isize); + xp2 = xp2.offset(-(2 as isize)); + wp1 = wp1.offset(2 as isize); + wp2 = wp2.offset(-(2 as isize)); + i += 1; + } + let mut yp_0: *mut f32 = f.as_mut_ptr(); + let t = trig; + i = 0; + while i < N4 { + let mut yc: kiss_fft_cpx = kiss_fft_cpx::zero(); + let mut t0: f32 = 0.; + let mut t1: f32 = 0.; + let mut re: f32 = 0.; + let mut im: f32 = 0.; + let mut yr: f32 = 0.; + let mut yi: f32 = 0.; + t0 = t[i as usize]; + t1 = t[(N4 + i) as usize]; + let fresh6 = yp_0; + yp_0 = yp_0.offset(1); + re = *fresh6; + let fresh7 = yp_0; + yp_0 = yp_0.offset(1); + im = *fresh7; + yr = re * t0 - im * t1; + yi = im * t0 + re * t1; + yc.re = yr; + yc.im = yi; + yc.re = scale * yc.re; + yc.im = scale * yc.im; + *f2.as_mut_ptr().offset(st.bitrev[i as usize] as isize) = yc; + i += 1; + } + opus_fft_impl(st, &mut f2); + let mut fp: *const kiss_fft_cpx = f2.as_mut_ptr(); + let mut yp1: *mut f32 = out; + let mut yp2: *mut f32 = out.offset((stride * (N2 - 1)) as isize); + let t = trig; + i = 0; + while i < N4 { + let mut yr_0: f32 = 0.; + let mut yi_0: f32 = 0.; + yr_0 = (*fp).im * t[(N4 + i) as usize] - (*fp).re * t[i as usize]; + yi_0 = (*fp).re * t[(N4 + i) as usize] + (*fp).im * t[i as usize]; + *yp1 = yr_0; + *yp2 = yi_0; + fp = fp.offset(1); + yp1 = yp1.offset((2 * stride) as isize); + yp2 = yp2.offset(-((2 * stride) as isize)); + i += 1; + } +} +pub unsafe fn clt_mdct_backward_c( + l: &mdct_lookup, + in_0: *mut f32, + out: *mut f32, + window: *const opus_val16, + overlap: i32, + shift: i32, + stride: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut N2: i32 = 0; + let mut N4: i32 = 0; + let trig = l.trig[shift as usize]; + N = l.n >> shift; + N2 = N >> 1; + N4 = N >> 2; + let mut xp1: *const f32 = in_0; + let mut xp2: *const f32 = in_0.offset((stride * (N2 - 1)) as isize); + let yp: *mut f32 = out.offset((overlap >> 1) as isize); + let t = trig; + let mut bitrev: *const i16 = l.kfft[shift as usize].bitrev.as_ptr(); + i = 0; + while i < N4 { + let mut rev: i32 = 0; + let mut yr: f32 = 0.; + let mut yi: f32 = 0.; + let fresh8 = bitrev; + bitrev = bitrev.offset(1); + rev = *fresh8 as i32; + yr = *xp2 * t[i as usize] + *xp1 * t[(N4 + i) as usize]; + yi = *xp1 * t[i as usize] - *xp2 * t[(N4 + i) as usize]; + *yp.offset((2 * rev + 1) as isize) = yr; + *yp.offset((2 * rev) as isize) = yi; + xp1 = xp1.offset((2 * stride) as isize); + xp2 = xp2.offset(-((2 * stride) as isize)); + i += 1; + } + opus_fft_impl( + l.kfft[shift as usize], + std::slice::from_raw_parts_mut( + out.offset((overlap >> 1) as isize) as *mut kiss_fft_cpx, + l.kfft[shift as usize].nfft, + ), + ); + let mut yp0: *mut f32 = out.offset((overlap >> 1) as isize); + let mut yp1: *mut f32 = out + .offset((overlap >> 1) as isize) + .offset(N2 as isize) + .offset(-(2 as isize)); + let t = trig; + i = 0; + while i < N4 + 1 >> 1 { + let mut re: f32 = 0.; + let mut im: f32 = 0.; + let mut yr_0: f32 = 0.; + let mut yi_0: f32 = 0.; + let mut t0: f32 = 0.; + let mut t1: f32 = 0.; + re = *yp0.offset(1 as isize); + im = *yp0.offset(0 as isize); + t0 = t[i as usize]; + t1 = t[(N4 + i) as usize]; + yr_0 = re * t0 + im * t1; + yi_0 = re * t1 - im * t0; + re = *yp1.offset(1 as isize); + im = *yp1.offset(0 as isize); + *yp0.offset(0 as isize) = yr_0; + *yp1.offset(1 as isize) = yi_0; + t0 = t[(N4 - i - 1) as usize]; + t1 = t[(N2 - i - 1) as usize]; + yr_0 = re * t0 + im * t1; + yi_0 = re * t1 - im * t0; + *yp1.offset(0 as isize) = yr_0; + *yp0.offset(1 as isize) = yi_0; + yp0 = yp0.offset(2 as isize); + yp1 = yp1.offset(-(2 as isize)); + i += 1; + } + let mut xp1_0: *mut f32 = out.offset(overlap as isize).offset(-(1 as isize)); + let mut yp1_0: *mut f32 = out; + let mut wp1: *const opus_val16 = window; + let mut wp2: *const opus_val16 = window.offset(overlap as isize).offset(-(1 as isize)); + i = 0; + while i < overlap / 2 { + let mut x1: f32 = 0.; + let mut x2: f32 = 0.; + x1 = *xp1_0; + x2 = *yp1_0; + let fresh9 = yp1_0; + yp1_0 = yp1_0.offset(1); + *fresh9 = *wp2 * x2 - *wp1 * x1; + let fresh10 = xp1_0; + xp1_0 = xp1_0.offset(-1); + *fresh10 = *wp1 * x2 + *wp2 * x1; + wp1 = wp1.offset(1); + wp2 = wp2.offset(-1); + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/celt/modes.rs b/vendor/unsafe-libopus/src/celt/modes.rs new file mode 100644 index 00000000..6c8ba09b --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/modes.rs @@ -0,0 +1,86 @@ +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusCustomMode { + pub(crate) Fs: i32, + pub(crate) overlap: i32, + pub(crate) nbEBands: i32, + pub(crate) effEBands: i32, + pub(crate) preemph: [opus_val16; 4], + pub(crate) eBands: *const i16, + pub(crate) maxLM: i32, + pub(crate) nbShortMdcts: i32, + pub(crate) shortMdctSize: i32, + pub(crate) nbAllocVectors: i32, + pub(crate) allocVectors: *const u8, + pub(crate) logN: *const i16, + pub(crate) window: *const opus_val16, + pub(crate) mdct: mdct_lookup<'static>, + pub(crate) cache: PulseCache, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct PulseCache { + pub size: i32, + pub index: *const i16, + pub bits: *const u8, + pub caps: *const u8, +} +pub const MAX_PERIOD: i32 = 1024; + +pub mod arch_h { + pub type opus_val16 = f32; +} +pub mod stddef_h { + pub const NULL: i32 = 0; +} + +pub mod static_modes_float_h; + +pub use self::arch_h::opus_val16; +pub use self::static_modes_float_h::{ + cache_bits50, cache_caps50, cache_index50, fft_bitrev120, fft_bitrev240, fft_bitrev480, + fft_bitrev60, fft_twiddles48000_960, logN400, static_mode_list, window120, +}; +pub use self::stddef_h::NULL; +use crate::celt::mdct::mdct_lookup; +use crate::src::opus_defines::{OPUS_BAD_ARG, OPUS_OK}; + +static eband5ms: [i16; 22] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100, +]; +static band_allocation: [u8; 231] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 80, 75, 69, 63, 56, 49, 40, + 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0, 110, 100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, + 26, 20, 12, 0, 0, 0, 0, 0, 0, 118, 110, 103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, + 15, 4, 0, 0, 0, 0, 126, 119, 112, 104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, + 1, 0, 0, 134, 127, 120, 114, 103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, + 1, 144, 137, 130, 124, 113, 107, 101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1, + 152, 145, 138, 132, 123, 117, 111, 105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1, 162, + 155, 148, 142, 133, 127, 121, 115, 108, 102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1, 172, + 165, 158, 152, 143, 137, 131, 125, 118, 112, 106, 100, 94, 87, 81, 75, 69, 63, 56, 45, 20, 200, + 200, 200, 200, 200, 200, 200, 200, 198, 193, 188, 183, 178, 173, 168, 163, 158, 153, 148, 129, + 104, +]; + +pub unsafe fn opus_custom_mode_create( + Fs: i32, + frame_size: i32, + error: *mut i32, +) -> *const OpusCustomMode { + // TODO: make static_mode_list non-mutable (requires Sync) + // TODO: maybe return Result instead of error code? + for mode in static_mode_list { + for j in 0..4 { + if Fs == (*mode).Fs && frame_size << j == (*mode).shortMdctSize * (*mode).nbShortMdcts { + if !error.is_null() { + *error = OPUS_OK; + } + return mode; + } + } + } + if !error.is_null() { + *error = OPUS_BAD_ARG; + } + return NULL as *mut OpusCustomMode; +} diff --git a/vendor/unsafe-libopus/src/celt/modes/static_modes_float_h.rs b/vendor/unsafe-libopus/src/celt/modes/static_modes_float_h.rs new file mode 100644 index 00000000..65282717 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/modes/static_modes_float_h.rs @@ -0,0 +1,883 @@ +#[rustfmt::skip] +pub static window120: [opus_val16; 120] = [ + 6.7286966e-05, 0.00060551348, 0.0016815970, 0.0032947962, 0.0054439943, + 0.0081276923, 0.011344001, 0.015090633, 0.019364886, 0.024163635, + 0.029483315, 0.035319905, 0.041668911, 0.048525347, 0.055883718, + 0.063737999, 0.072081616, 0.080907428, 0.090207705, 0.099974111, + 0.11019769, 0.12086883, 0.13197729, 0.14351214, 0.15546177, + 0.16781389, 0.18055550, 0.19367290, 0.20715171, 0.22097682, + 0.23513243, 0.24960208, 0.26436860, 0.27941419, 0.29472040, + 0.31026818, 0.32603788, 0.34200931, 0.35816177, 0.37447407, + 0.39092462, 0.40749142, 0.42415215, 0.44088423, 0.45766484, + 0.47447104, 0.49127978, 0.50806798, 0.52481261, 0.54149077, + 0.55807973, 0.57455701, 0.59090049, 0.60708841, 0.62309951, + 0.63891306, 0.65450896, 0.66986776, 0.68497077, 0.69980010, + 0.71433873, 0.72857055, 0.74248043, 0.75605424, 0.76927895, + 0.78214257, 0.79463430, 0.80674445, 0.81846456, 0.82978733, + 0.84070669, 0.85121779, 0.86131698, 0.87100183, 0.88027111, + 0.88912479, 0.89756398, 0.90559094, 0.91320904, 0.92042270, + 0.92723738, 0.93365955, 0.93969656, 0.94535671, 0.95064907, + 0.95558353, 0.96017067, 0.96442171, 0.96834849, 0.97196334, + 0.97527906, 0.97830883, 0.98106616, 0.98356480, 0.98581869, + 0.98784191, 0.98964856, 0.99125274, 0.99266849, 0.99390969, + 0.99499004, 0.99592297, 0.99672162, 0.99739874, 0.99796667, + 0.99843728, 0.99882195, 0.99913147, 0.99937606, 0.99956527, + 0.99970802, 0.99981248, 0.99988613, 0.99993565, 0.99996697, + 0.99998518, 0.99999457, 0.99999859, 0.99999982, 1.0000000, +]; +pub static logN400: [i16; 21] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, +]; +#[rustfmt::skip] +pub static cache_index50: [i16; 105] = [ + -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, + 82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, + 41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, + 41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, + 318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, + 305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, + 240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, +]; +#[rustfmt::skip] +pub static cache_bits50: [u8; 392] = [ + 40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, + 31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, + 51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, + 66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, + 64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, + 94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, + 124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, + 97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, + 142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, + 28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, + 153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, + 229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, + 166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, + 86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, + 25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, + 185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, + 110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, + 74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, + 163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, + 228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, + 90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, + 87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, + 106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, + 224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, + 182, 234, +]; +#[rustfmt::skip] +pub static cache_caps50: [u8; 168] = [ + 224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, + 178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, + 240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, + 160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, + 138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, + 204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, + 185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, + 207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, + 188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, + 204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, + 140, 66, 40, +]; + +macro_rules! c { + ($re:literal, $im:literal) => { + kiss_twiddle_cpx::new($re, $im) + }; +} + +#[rustfmt::skip] +pub static fft_twiddles48000_960: [kiss_twiddle_cpx; 480] = [ + c!(1.0000000, -0.0000000), c!(0.99991433, -0.013089596), + c!(0.99965732, -0.026176948), c!(0.99922904, -0.039259816), + c!(0.99862953, -0.052335956), c!(0.99785892, -0.065403129), + c!(0.99691733, -0.078459096), c!(0.99580493, -0.091501619), + c!(0.99452190, -0.10452846), c!(0.99306846, -0.11753740), + c!(0.99144486, -0.13052619), c!(0.98965139, -0.14349262), + c!(0.98768834, -0.15643447), c!(0.98555606, -0.16934950), + c!(0.98325491, -0.18223553), c!(0.98078528, -0.19509032), + c!(0.97814760, -0.20791169), c!(0.97534232, -0.22069744), + c!(0.97236992, -0.23344536), c!(0.96923091, -0.24615329), + c!(0.96592583, -0.25881905), c!(0.96245524, -0.27144045), + c!(0.95881973, -0.28401534), c!(0.95501994, -0.29654157), + c!(0.95105652, -0.30901699), c!(0.94693013, -0.32143947), + c!(0.94264149, -0.33380686), c!(0.93819134, -0.34611706), + c!(0.93358043, -0.35836795), c!(0.92880955, -0.37055744), + c!(0.92387953, -0.38268343), c!(0.91879121, -0.39474386), + c!(0.91354546, -0.40673664), c!(0.90814317, -0.41865974), + c!(0.90258528, -0.43051110), c!(0.89687274, -0.44228869), + c!(0.89100652, -0.45399050), c!(0.88498764, -0.46561452), + c!(0.87881711, -0.47715876), c!(0.87249601, -0.48862124), + c!(0.86602540, -0.50000000), c!(0.85940641, -0.51129309), + c!(0.85264016, -0.52249856), c!(0.84572782, -0.53361452), + c!(0.83867057, -0.54463904), c!(0.83146961, -0.55557023), + c!(0.82412619, -0.56640624), c!(0.81664156, -0.57714519), + c!(0.80901699, -0.58778525), c!(0.80125381, -0.59832460), + c!(0.79335334, -0.60876143), c!(0.78531693, -0.61909395), + c!(0.77714596, -0.62932039), c!(0.76884183, -0.63943900), + c!(0.76040597, -0.64944805), c!(0.75183981, -0.65934582), + c!(0.74314483, -0.66913061), c!(0.73432251, -0.67880075), + c!(0.72537437, -0.68835458), c!(0.71630194, -0.69779046), + c!(0.70710678, -0.70710678), c!(0.69779046, -0.71630194), + c!(0.68835458, -0.72537437), c!(0.67880075, -0.73432251), + c!(0.66913061, -0.74314483), c!(0.65934582, -0.75183981), + c!(0.64944805, -0.76040597), c!(0.63943900, -0.76884183), + c!(0.62932039, -0.77714596), c!(0.61909395, -0.78531693), + c!(0.60876143, -0.79335334), c!(0.59832460, -0.80125381), + c!(0.58778525, -0.80901699), c!(0.57714519, -0.81664156), + c!(0.56640624, -0.82412619), c!(0.55557023, -0.83146961), + c!(0.54463904, -0.83867057), c!(0.53361452, -0.84572782), + c!(0.52249856, -0.85264016), c!(0.51129309, -0.85940641), + c!(0.50000000, -0.86602540), c!(0.48862124, -0.87249601), + c!(0.47715876, -0.87881711), c!(0.46561452, -0.88498764), + c!(0.45399050, -0.89100652), c!(0.44228869, -0.89687274), + c!(0.43051110, -0.90258528), c!(0.41865974, -0.90814317), + c!(0.40673664, -0.91354546), c!(0.39474386, -0.91879121), + c!(0.38268343, -0.92387953), c!(0.37055744, -0.92880955), + c!(0.35836795, -0.93358043), c!(0.34611706, -0.93819134), + c!(0.33380686, -0.94264149), c!(0.32143947, -0.94693013), + c!(0.30901699, -0.95105652), c!(0.29654157, -0.95501994), + c!(0.28401534, -0.95881973), c!(0.27144045, -0.96245524), + c!(0.25881905, -0.96592583), c!(0.24615329, -0.96923091), + c!(0.23344536, -0.97236992), c!(0.22069744, -0.97534232), + c!(0.20791169, -0.97814760), c!(0.19509032, -0.98078528), + c!(0.18223553, -0.98325491), c!(0.16934950, -0.98555606), + c!(0.15643447, -0.98768834), c!(0.14349262, -0.98965139), + c!(0.13052619, -0.99144486), c!(0.11753740, -0.99306846), + c!(0.10452846, -0.99452190), c!(0.091501619, -0.99580493), + c!(0.078459096, -0.99691733), c!(0.065403129, -0.99785892), + c!(0.052335956, -0.99862953), c!(0.039259816, -0.99922904), + c!(0.026176948, -0.99965732), c!(0.013089596, -0.99991433), + c!(6.1230318e-17, -1.0000000), c!(-0.013089596, -0.99991433), + c!(-0.026176948, -0.99965732), c!(-0.039259816, -0.99922904), + c!(-0.052335956, -0.99862953), c!(-0.065403129, -0.99785892), + c!(-0.078459096, -0.99691733), c!(-0.091501619, -0.99580493), + c!(-0.10452846, -0.99452190), c!(-0.11753740, -0.99306846), + c!(-0.13052619, -0.99144486), c!(-0.14349262, -0.98965139), + c!(-0.15643447, -0.98768834), c!(-0.16934950, -0.98555606), + c!(-0.18223553, -0.98325491), c!(-0.19509032, -0.98078528), + c!(-0.20791169, -0.97814760), c!(-0.22069744, -0.97534232), + c!(-0.23344536, -0.97236992), c!(-0.24615329, -0.96923091), + c!(-0.25881905, -0.96592583), c!(-0.27144045, -0.96245524), + c!(-0.28401534, -0.95881973), c!(-0.29654157, -0.95501994), + c!(-0.30901699, -0.95105652), c!(-0.32143947, -0.94693013), + c!(-0.33380686, -0.94264149), c!(-0.34611706, -0.93819134), + c!(-0.35836795, -0.93358043), c!(-0.37055744, -0.92880955), + c!(-0.38268343, -0.92387953), c!(-0.39474386, -0.91879121), + c!(-0.40673664, -0.91354546), c!(-0.41865974, -0.90814317), + c!(-0.43051110, -0.90258528), c!(-0.44228869, -0.89687274), + c!(-0.45399050, -0.89100652), c!(-0.46561452, -0.88498764), + c!(-0.47715876, -0.87881711), c!(-0.48862124, -0.87249601), + c!(-0.50000000, -0.86602540), c!(-0.51129309, -0.85940641), + c!(-0.52249856, -0.85264016), c!(-0.53361452, -0.84572782), + c!(-0.54463904, -0.83867057), c!(-0.55557023, -0.83146961), + c!(-0.56640624, -0.82412619), c!(-0.57714519, -0.81664156), + c!(-0.58778525, -0.80901699), c!(-0.59832460, -0.80125381), + c!(-0.60876143, -0.79335334), c!(-0.61909395, -0.78531693), + c!(-0.62932039, -0.77714596), c!(-0.63943900, -0.76884183), + c!(-0.64944805, -0.76040597), c!(-0.65934582, -0.75183981), + c!(-0.66913061, -0.74314483), c!(-0.67880075, -0.73432251), + c!(-0.68835458, -0.72537437), c!(-0.69779046, -0.71630194), + c!(-0.70710678, -0.70710678), c!(-0.71630194, -0.69779046), + c!(-0.72537437, -0.68835458), c!(-0.73432251, -0.67880075), + c!(-0.74314483, -0.66913061), c!(-0.75183981, -0.65934582), + c!(-0.76040597, -0.64944805), c!(-0.76884183, -0.63943900), + c!(-0.77714596, -0.62932039), c!(-0.78531693, -0.61909395), + c!(-0.79335334, -0.60876143), c!(-0.80125381, -0.59832460), + c!(-0.80901699, -0.58778525), c!(-0.81664156, -0.57714519), + c!(-0.82412619, -0.56640624), c!(-0.83146961, -0.55557023), + c!(-0.83867057, -0.54463904), c!(-0.84572782, -0.53361452), + c!(-0.85264016, -0.52249856), c!(-0.85940641, -0.51129309), + c!(-0.86602540, -0.50000000), c!(-0.87249601, -0.48862124), + c!(-0.87881711, -0.47715876), c!(-0.88498764, -0.46561452), + c!(-0.89100652, -0.45399050), c!(-0.89687274, -0.44228869), + c!(-0.90258528, -0.43051110), c!(-0.90814317, -0.41865974), + c!(-0.91354546, -0.40673664), c!(-0.91879121, -0.39474386), + c!(-0.92387953, -0.38268343), c!(-0.92880955, -0.37055744), + c!(-0.93358043, -0.35836795), c!(-0.93819134, -0.34611706), + c!(-0.94264149, -0.33380686), c!(-0.94693013, -0.32143947), + c!(-0.95105652, -0.30901699), c!(-0.95501994, -0.29654157), + c!(-0.95881973, -0.28401534), c!(-0.96245524, -0.27144045), + c!(-0.96592583, -0.25881905), c!(-0.96923091, -0.24615329), + c!(-0.97236992, -0.23344536), c!(-0.97534232, -0.22069744), + c!(-0.97814760, -0.20791169), c!(-0.98078528, -0.19509032), + c!(-0.98325491, -0.18223553), c!(-0.98555606, -0.16934950), + c!(-0.98768834, -0.15643447), c!(-0.98965139, -0.14349262), + c!(-0.99144486, -0.13052619), c!(-0.99306846, -0.11753740), + c!(-0.99452190, -0.10452846), c!(-0.99580493, -0.091501619), + c!(-0.99691733, -0.078459096), c!(-0.99785892, -0.065403129), + c!(-0.99862953, -0.052335956), c!(-0.99922904, -0.039259816), + c!(-0.99965732, -0.026176948), c!(-0.99991433, -0.013089596), + c!(-1.0000000, -1.2246064e-16), c!(-0.99991433, 0.013089596), + c!(-0.99965732, 0.026176948), c!(-0.99922904, 0.039259816), + c!(-0.99862953, 0.052335956), c!(-0.99785892, 0.065403129), + c!(-0.99691733, 0.078459096), c!(-0.99580493, 0.091501619), + c!(-0.99452190, 0.10452846), c!(-0.99306846, 0.11753740), + c!(-0.99144486, 0.13052619), c!(-0.98965139, 0.14349262), + c!(-0.98768834, 0.15643447), c!(-0.98555606, 0.16934950), + c!(-0.98325491, 0.18223553), c!(-0.98078528, 0.19509032), + c!(-0.97814760, 0.20791169), c!(-0.97534232, 0.22069744), + c!(-0.97236992, 0.23344536), c!(-0.96923091, 0.24615329), + c!(-0.96592583, 0.25881905), c!(-0.96245524, 0.27144045), + c!(-0.95881973, 0.28401534), c!(-0.95501994, 0.29654157), + c!(-0.95105652, 0.30901699), c!(-0.94693013, 0.32143947), + c!(-0.94264149, 0.33380686), c!(-0.93819134, 0.34611706), + c!(-0.93358043, 0.35836795), c!(-0.92880955, 0.37055744), + c!(-0.92387953, 0.38268343), c!(-0.91879121, 0.39474386), + c!(-0.91354546, 0.40673664), c!(-0.90814317, 0.41865974), + c!(-0.90258528, 0.43051110), c!(-0.89687274, 0.44228869), + c!(-0.89100652, 0.45399050), c!(-0.88498764, 0.46561452), + c!(-0.87881711, 0.47715876), c!(-0.87249601, 0.48862124), + c!(-0.86602540, 0.50000000), c!(-0.85940641, 0.51129309), + c!(-0.85264016, 0.52249856), c!(-0.84572782, 0.53361452), + c!(-0.83867057, 0.54463904), c!(-0.83146961, 0.55557023), + c!(-0.82412619, 0.56640624), c!(-0.81664156, 0.57714519), + c!(-0.80901699, 0.58778525), c!(-0.80125381, 0.59832460), + c!(-0.79335334, 0.60876143), c!(-0.78531693, 0.61909395), + c!(-0.77714596, 0.62932039), c!(-0.76884183, 0.63943900), + c!(-0.76040597, 0.64944805), c!(-0.75183981, 0.65934582), + c!(-0.74314483, 0.66913061), c!(-0.73432251, 0.67880075), + c!(-0.72537437, 0.68835458), c!(-0.71630194, 0.69779046), + c!(-0.70710678, 0.70710678), c!(-0.69779046, 0.71630194), + c!(-0.68835458, 0.72537437), c!(-0.67880075, 0.73432251), + c!(-0.66913061, 0.74314483), c!(-0.65934582, 0.75183981), + c!(-0.64944805, 0.76040597), c!(-0.63943900, 0.76884183), + c!(-0.62932039, 0.77714596), c!(-0.61909395, 0.78531693), + c!(-0.60876143, 0.79335334), c!(-0.59832460, 0.80125381), + c!(-0.58778525, 0.80901699), c!(-0.57714519, 0.81664156), + c!(-0.56640624, 0.82412619), c!(-0.55557023, 0.83146961), + c!(-0.54463904, 0.83867057), c!(-0.53361452, 0.84572782), + c!(-0.52249856, 0.85264016), c!(-0.51129309, 0.85940641), + c!(-0.50000000, 0.86602540), c!(-0.48862124, 0.87249601), + c!(-0.47715876, 0.87881711), c!(-0.46561452, 0.88498764), + c!(-0.45399050, 0.89100652), c!(-0.44228869, 0.89687274), + c!(-0.43051110, 0.90258528), c!(-0.41865974, 0.90814317), + c!(-0.40673664, 0.91354546), c!(-0.39474386, 0.91879121), + c!(-0.38268343, 0.92387953), c!(-0.37055744, 0.92880955), + c!(-0.35836795, 0.93358043), c!(-0.34611706, 0.93819134), + c!(-0.33380686, 0.94264149), c!(-0.32143947, 0.94693013), + c!(-0.30901699, 0.95105652), c!(-0.29654157, 0.95501994), + c!(-0.28401534, 0.95881973), c!(-0.27144045, 0.96245524), + c!(-0.25881905, 0.96592583), c!(-0.24615329, 0.96923091), + c!(-0.23344536, 0.97236992), c!(-0.22069744, 0.97534232), + c!(-0.20791169, 0.97814760), c!(-0.19509032, 0.98078528), + c!(-0.18223553, 0.98325491), c!(-0.16934950, 0.98555606), + c!(-0.15643447, 0.98768834), c!(-0.14349262, 0.98965139), + c!(-0.13052619, 0.99144486), c!(-0.11753740, 0.99306846), + c!(-0.10452846, 0.99452190), c!(-0.091501619, 0.99580493), + c!(-0.078459096, 0.99691733), c!(-0.065403129, 0.99785892), + c!(-0.052335956, 0.99862953), c!(-0.039259816, 0.99922904), + c!(-0.026176948, 0.99965732), c!(-0.013089596, 0.99991433), + c!(-1.8369095e-16, 1.0000000), c!(0.013089596, 0.99991433), + c!(0.026176948, 0.99965732), c!(0.039259816, 0.99922904), + c!(0.052335956, 0.99862953), c!(0.065403129, 0.99785892), + c!(0.078459096, 0.99691733), c!(0.091501619, 0.99580493), + c!(0.10452846, 0.99452190), c!(0.11753740, 0.99306846), + c!(0.13052619, 0.99144486), c!(0.14349262, 0.98965139), + c!(0.15643447, 0.98768834), c!(0.16934950, 0.98555606), + c!(0.18223553, 0.98325491), c!(0.19509032, 0.98078528), + c!(0.20791169, 0.97814760), c!(0.22069744, 0.97534232), + c!(0.23344536, 0.97236992), c!(0.24615329, 0.96923091), + c!(0.25881905, 0.96592583), c!(0.27144045, 0.96245524), + c!(0.28401534, 0.95881973), c!(0.29654157, 0.95501994), + c!(0.30901699, 0.95105652), c!(0.32143947, 0.94693013), + c!(0.33380686, 0.94264149), c!(0.34611706, 0.93819134), + c!(0.35836795, 0.93358043), c!(0.37055744, 0.92880955), + c!(0.38268343, 0.92387953), c!(0.39474386, 0.91879121), + c!(0.40673664, 0.91354546), c!(0.41865974, 0.90814317), + c!(0.43051110, 0.90258528), c!(0.44228869, 0.89687274), + c!(0.45399050, 0.89100652), c!(0.46561452, 0.88498764), + c!(0.47715876, 0.87881711), c!(0.48862124, 0.87249601), + c!(0.50000000, 0.86602540), c!(0.51129309, 0.85940641), + c!(0.52249856, 0.85264016), c!(0.53361452, 0.84572782), + c!(0.54463904, 0.83867057), c!(0.55557023, 0.83146961), + c!(0.56640624, 0.82412619), c!(0.57714519, 0.81664156), + c!(0.58778525, 0.80901699), c!(0.59832460, 0.80125381), + c!(0.60876143, 0.79335334), c!(0.61909395, 0.78531693), + c!(0.62932039, 0.77714596), c!(0.63943900, 0.76884183), + c!(0.64944805, 0.76040597), c!(0.65934582, 0.75183981), + c!(0.66913061, 0.74314483), c!(0.67880075, 0.73432251), + c!(0.68835458, 0.72537437), c!(0.69779046, 0.71630194), + c!(0.70710678, 0.70710678), c!(0.71630194, 0.69779046), + c!(0.72537437, 0.68835458), c!(0.73432251, 0.67880075), + c!(0.74314483, 0.66913061), c!(0.75183981, 0.65934582), + c!(0.76040597, 0.64944805), c!(0.76884183, 0.63943900), + c!(0.77714596, 0.62932039), c!(0.78531693, 0.61909395), + c!(0.79335334, 0.60876143), c!(0.80125381, 0.59832460), + c!(0.80901699, 0.58778525), c!(0.81664156, 0.57714519), + c!(0.82412619, 0.56640624), c!(0.83146961, 0.55557023), + c!(0.83867057, 0.54463904), c!(0.84572782, 0.53361452), + c!(0.85264016, 0.52249856), c!(0.85940641, 0.51129309), + c!(0.86602540, 0.50000000), c!(0.87249601, 0.48862124), + c!(0.87881711, 0.47715876), c!(0.88498764, 0.46561452), + c!(0.89100652, 0.45399050), c!(0.89687274, 0.44228869), + c!(0.90258528, 0.43051110), c!(0.90814317, 0.41865974), + c!(0.91354546, 0.40673664), c!(0.91879121, 0.39474386), + c!(0.92387953, 0.38268343), c!(0.92880955, 0.37055744), + c!(0.93358043, 0.35836795), c!(0.93819134, 0.34611706), + c!(0.94264149, 0.33380686), c!(0.94693013, 0.32143947), + c!(0.95105652, 0.30901699), c!(0.95501994, 0.29654157), + c!(0.95881973, 0.28401534), c!(0.96245524, 0.27144045), + c!(0.96592583, 0.25881905), c!(0.96923091, 0.24615329), + c!(0.97236992, 0.23344536), c!(0.97534232, 0.22069744), + c!(0.97814760, 0.20791169), c!(0.98078528, 0.19509032), + c!(0.98325491, 0.18223553), c!(0.98555606, 0.16934950), + c!(0.98768834, 0.15643447), c!(0.98965139, 0.14349262), + c!(0.99144486, 0.13052619), c!(0.99306846, 0.11753740), + c!(0.99452190, 0.10452846), c!(0.99580493, 0.091501619), + c!(0.99691733, 0.078459096), c!(0.99785892, 0.065403129), + c!(0.99862953, 0.052335956), c!(0.99922904, 0.039259816), + c!(0.99965732, 0.026176948), c!(0.99991433, 0.013089596), +]; +#[rustfmt::skip] +pub static fft_bitrev480: [i16; 480] = [ + 0, 96, 192, 288, 384, 32, 128, 224, 320, 416, 64, 160, 256, 352, 448, + 8, 104, 200, 296, 392, 40, 136, 232, 328, 424, 72, 168, 264, 360, 456, + 16, 112, 208, 304, 400, 48, 144, 240, 336, 432, 80, 176, 272, 368, 464, + 24, 120, 216, 312, 408, 56, 152, 248, 344, 440, 88, 184, 280, 376, 472, + 4, 100, 196, 292, 388, 36, 132, 228, 324, 420, 68, 164, 260, 356, 452, + 12, 108, 204, 300, 396, 44, 140, 236, 332, 428, 76, 172, 268, 364, 460, + 20, 116, 212, 308, 404, 52, 148, 244, 340, 436, 84, 180, 276, 372, 468, + 28, 124, 220, 316, 412, 60, 156, 252, 348, 444, 92, 188, 284, 380, 476, + 1, 97, 193, 289, 385, 33, 129, 225, 321, 417, 65, 161, 257, 353, 449, + 9, 105, 201, 297, 393, 41, 137, 233, 329, 425, 73, 169, 265, 361, 457, + 17, 113, 209, 305, 401, 49, 145, 241, 337, 433, 81, 177, 273, 369, 465, + 25, 121, 217, 313, 409, 57, 153, 249, 345, 441, 89, 185, 281, 377, 473, + 5, 101, 197, 293, 389, 37, 133, 229, 325, 421, 69, 165, 261, 357, 453, + 13, 109, 205, 301, 397, 45, 141, 237, 333, 429, 77, 173, 269, 365, 461, + 21, 117, 213, 309, 405, 53, 149, 245, 341, 437, 85, 181, 277, 373, 469, + 29, 125, 221, 317, 413, 61, 157, 253, 349, 445, 93, 189, 285, 381, 477, + 2, 98, 194, 290, 386, 34, 130, 226, 322, 418, 66, 162, 258, 354, 450, + 10, 106, 202, 298, 394, 42, 138, 234, 330, 426, 74, 170, 266, 362, 458, + 18, 114, 210, 306, 402, 50, 146, 242, 338, 434, 82, 178, 274, 370, 466, + 26, 122, 218, 314, 410, 58, 154, 250, 346, 442, 90, 186, 282, 378, 474, + 6, 102, 198, 294, 390, 38, 134, 230, 326, 422, 70, 166, 262, 358, 454, + 14, 110, 206, 302, 398, 46, 142, 238, 334, 430, 78, 174, 270, 366, 462, + 22, 118, 214, 310, 406, 54, 150, 246, 342, 438, 86, 182, 278, 374, 470, + 30, 126, 222, 318, 414, 62, 158, 254, 350, 446, 94, 190, 286, 382, 478, + 3, 99, 195, 291, 387, 35, 131, 227, 323, 419, 67, 163, 259, 355, 451, + 11, 107, 203, 299, 395, 43, 139, 235, 331, 427, 75, 171, 267, 363, 459, + 19, 115, 211, 307, 403, 51, 147, 243, 339, 435, 83, 179, 275, 371, 467, + 27, 123, 219, 315, 411, 59, 155, 251, 347, 443, 91, 187, 283, 379, 475, + 7, 103, 199, 295, 391, 39, 135, 231, 327, 423, 71, 167, 263, 359, 455, + 15, 111, 207, 303, 399, 47, 143, 239, 335, 431, 79, 175, 271, 367, 463, + 23, 119, 215, 311, 407, 55, 151, 247, 343, 439, 87, 183, 279, 375, 471, + 31, 127, 223, 319, 415, 63, 159, 255, 351, 447, 95, 191, 287, 383, 479, +]; +#[rustfmt::skip] +pub static fft_bitrev240: [i16; 240] = [ + 0, 48, 96, 144, 192, 16, 64, 112, 160, 208, 32, 80, 128, 176, 224, + 4, 52, 100, 148, 196, 20, 68, 116, 164, 212, 36, 84, 132, 180, 228, + 8, 56, 104, 152, 200, 24, 72, 120, 168, 216, 40, 88, 136, 184, 232, + 12, 60, 108, 156, 204, 28, 76, 124, 172, 220, 44, 92, 140, 188, 236, + 1, 49, 97, 145, 193, 17, 65, 113, 161, 209, 33, 81, 129, 177, 225, + 5, 53, 101, 149, 197, 21, 69, 117, 165, 213, 37, 85, 133, 181, 229, + 9, 57, 105, 153, 201, 25, 73, 121, 169, 217, 41, 89, 137, 185, 233, + 13, 61, 109, 157, 205, 29, 77, 125, 173, 221, 45, 93, 141, 189, 237, + 2, 50, 98, 146, 194, 18, 66, 114, 162, 210, 34, 82, 130, 178, 226, + 6, 54, 102, 150, 198, 22, 70, 118, 166, 214, 38, 86, 134, 182, 230, + 10, 58, 106, 154, 202, 26, 74, 122, 170, 218, 42, 90, 138, 186, 234, + 14, 62, 110, 158, 206, 30, 78, 126, 174, 222, 46, 94, 142, 190, 238, + 3, 51, 99, 147, 195, 19, 67, 115, 163, 211, 35, 83, 131, 179, 227, + 7, 55, 103, 151, 199, 23, 71, 119, 167, 215, 39, 87, 135, 183, 231, + 11, 59, 107, 155, 203, 27, 75, 123, 171, 219, 43, 91, 139, 187, 235, + 15, 63, 111, 159, 207, 31, 79, 127, 175, 223, 47, 95, 143, 191, 239, +]; +#[rustfmt::skip] +pub static fft_bitrev120: [i16; 120] = [ + 0, 24, 48, 72, 96, 8, 32, 56, 80, 104, 16, 40, 64, 88, 112, + 4, 28, 52, 76, 100, 12, 36, 60, 84, 108, 20, 44, 68, 92, 116, + 1, 25, 49, 73, 97, 9, 33, 57, 81, 105, 17, 41, 65, 89, 113, + 5, 29, 53, 77, 101, 13, 37, 61, 85, 109, 21, 45, 69, 93, 117, + 2, 26, 50, 74, 98, 10, 34, 58, 82, 106, 18, 42, 66, 90, 114, + 6, 30, 54, 78, 102, 14, 38, 62, 86, 110, 22, 46, 70, 94, 118, + 3, 27, 51, 75, 99, 11, 35, 59, 83, 107, 19, 43, 67, 91, 115, + 7, 31, 55, 79, 103, 15, 39, 63, 87, 111, 23, 47, 71, 95, 119, +]; +#[rustfmt::skip] +pub static fft_bitrev60: [i16; 60] = [ + 0, 12, 24, 36, 48, 4, 16, 28, 40, 52, 8, 20, 32, 44, 56, + 1, 13, 25, 37, 49, 5, 17, 29, 41, 53, 9, 21, 33, 45, 57, + 2, 14, 26, 38, 50, 6, 18, 30, 42, 54, 10, 22, 34, 46, 58, + 3, 15, 27, 39, 51, 7, 19, 31, 43, 55, 11, 23, 35, 47, 59, +]; +pub static fft_state48000_960_0: kiss_fft_state = kiss_fft_state { + nfft: 480, + scale: 0.002083333, + shift: -1, + factors: [ + (5, 96), + (3, 32), + (4, 8), + (2, 4), + (4, 1), + (0, 0), + (0, 0), + (0, 0), + ], + bitrev: &fft_bitrev480, + twiddles: &fft_twiddles48000_960, +}; +pub static fft_state48000_960_1: kiss_fft_state = kiss_fft_state { + nfft: 240, + scale: 0.004166667, + shift: 1, + factors: [ + (5, 48), + (3, 16), + (4, 4), + (4, 1), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + ], + bitrev: &fft_bitrev240, + twiddles: &fft_twiddles48000_960, +}; +pub static fft_state48000_960_2: kiss_fft_state = kiss_fft_state { + nfft: 120, + scale: 0.008333333, + shift: 2, + factors: [ + (5, 24), + (3, 8), + (2, 4), + (4, 1), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + ], + bitrev: &fft_bitrev120, + twiddles: &fft_twiddles48000_960, +}; +pub static fft_state48000_960_3: kiss_fft_state = kiss_fft_state { + nfft: 60, + scale: 0.016666667, + shift: 3, + factors: [ + (5, 12), + (3, 4), + (4, 1), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + ], + bitrev: &fft_bitrev60, + twiddles: &fft_twiddles48000_960, +}; +#[rustfmt::skip] +pub static mdct_twiddles960: [&[f32]; 4] = [ + &[ + 0.99999994, 0.99999321, 0.99997580, 0.99994773, 0.99990886, + 0.99985933, 0.99979913, 0.99972820, 0.99964654, 0.99955416, + 0.99945110, 0.99933738, 0.99921292, 0.99907774, 0.99893188, + 0.99877530, 0.99860805, 0.99843007, 0.99824142, 0.99804211, + 0.99783206, 0.99761140, 0.99737996, 0.99713790, 0.99688518, + 0.99662173, 0.99634761, 0.99606287, 0.99576741, 0.99546129, + 0.99514455, 0.99481714, 0.99447906, 0.99413031, 0.99377096, + 0.99340093, 0.99302030, 0.99262899, 0.99222708, 0.99181455, + 0.99139136, 0.99095762, 0.99051321, 0.99005818, 0.98959261, + 0.98911643, 0.98862964, 0.98813224, 0.98762429, 0.98710573, + 0.98657662, 0.98603696, 0.98548669, 0.98492593, 0.98435456, + 0.98377270, 0.98318028, 0.98257732, 0.98196387, 0.98133987, + 0.98070538, 0.98006040, 0.97940493, 0.97873890, 0.97806245, + 0.97737551, 0.97667813, 0.97597027, 0.97525197, 0.97452319, + 0.97378403, 0.97303438, 0.97227436, 0.97150391, 0.97072303, + 0.96993178, 0.96913016, 0.96831810, 0.96749574, 0.96666300, + 0.96581990, 0.96496642, 0.96410263, 0.96322852, 0.96234411, + 0.96144938, 0.96054435, 0.95962906, 0.95870346, 0.95776761, + 0.95682150, 0.95586514, 0.95489854, 0.95392174, 0.95293468, + 0.95193744, 0.95093000, 0.94991243, 0.94888461, 0.94784665, + 0.94679856, 0.94574034, 0.94467193, 0.94359344, 0.94250488, + 0.94140619, 0.94029742, 0.93917859, 0.93804967, 0.93691075, + 0.93576175, 0.93460274, 0.93343377, 0.93225473, 0.93106574, + 0.92986679, 0.92865789, 0.92743903, 0.92621022, 0.92497152, + 0.92372292, 0.92246443, 0.92119598, 0.91991776, 0.91862965, + 0.91733170, 0.91602397, 0.91470635, 0.91337901, 0.91204184, + 0.91069490, 0.90933824, 0.90797186, 0.90659571, 0.90520984, + 0.90381432, 0.90240908, 0.90099424, 0.89956969, 0.89813554, + 0.89669174, 0.89523834, 0.89377540, 0.89230281, 0.89082074, + 0.88932908, 0.88782793, 0.88631725, 0.88479710, 0.88326746, + 0.88172835, 0.88017982, 0.87862182, 0.87705445, 0.87547767, + 0.87389153, 0.87229604, 0.87069118, 0.86907703, 0.86745358, + 0.86582077, 0.86417878, 0.86252749, 0.86086690, 0.85919720, + 0.85751826, 0.85583007, 0.85413277, 0.85242635, 0.85071075, + 0.84898609, 0.84725231, 0.84550947, 0.84375757, 0.84199661, + 0.84022665, 0.83844769, 0.83665979, 0.83486289, 0.83305705, + 0.83124226, 0.82941860, 0.82758605, 0.82574469, 0.82389444, + 0.82203537, 0.82016748, 0.81829083, 0.81640542, 0.81451124, + 0.81260836, 0.81069672, 0.80877650, 0.80684757, 0.80490994, + 0.80296379, 0.80100900, 0.79904562, 0.79707366, 0.79509324, + 0.79310423, 0.79110676, 0.78910083, 0.78708643, 0.78506362, + 0.78303236, 0.78099275, 0.77894479, 0.77688843, 0.77482378, + 0.77275085, 0.77066964, 0.76858020, 0.76648247, 0.76437658, + 0.76226246, 0.76014024, 0.75800985, 0.75587130, 0.75372469, + 0.75157005, 0.74940729, 0.74723655, 0.74505776, 0.74287105, + 0.74067634, 0.73847371, 0.73626316, 0.73404479, 0.73181850, + 0.72958434, 0.72734243, 0.72509271, 0.72283524, 0.72057003, + 0.71829706, 0.71601641, 0.71372813, 0.71143216, 0.70912862, + 0.70681745, 0.70449871, 0.70217246, 0.69983864, 0.69749737, + 0.69514859, 0.69279242, 0.69042879, 0.68805778, 0.68567938, + 0.68329364, 0.68090063, 0.67850029, 0.67609268, 0.67367786, + 0.67125577, 0.66882652, 0.66639012, 0.66394657, 0.66149592, + 0.65903819, 0.65657341, 0.65410155, 0.65162271, 0.64913690, + 0.64664418, 0.64414448, 0.64163786, 0.63912445, 0.63660413, + 0.63407701, 0.63154310, 0.62900239, 0.62645501, 0.62390089, + 0.62134010, 0.61877263, 0.61619854, 0.61361790, 0.61103064, + 0.60843682, 0.60583651, 0.60322970, 0.60061646, 0.59799677, + 0.59537065, 0.59273821, 0.59009939, 0.58745426, 0.58480281, + 0.58214509, 0.57948118, 0.57681108, 0.57413477, 0.57145232, + 0.56876373, 0.56606907, 0.56336832, 0.56066155, 0.55794877, + 0.55523002, 0.55250537, 0.54977477, 0.54703826, 0.54429591, + 0.54154772, 0.53879374, 0.53603399, 0.53326851, 0.53049731, + 0.52772039, 0.52493787, 0.52214974, 0.51935595, 0.51655668, + 0.51375180, 0.51094145, 0.50812566, 0.50530440, 0.50247771, + 0.49964568, 0.49680826, 0.49396557, 0.49111754, 0.48826426, + 0.48540577, 0.48254207, 0.47967321, 0.47679919, 0.47392011, + 0.47103590, 0.46814668, 0.46525243, 0.46235323, 0.45944905, + 0.45653993, 0.45362595, 0.45070711, 0.44778344, 0.44485497, + 0.44192174, 0.43898380, 0.43604112, 0.43309379, 0.43014181, + 0.42718524, 0.42422408, 0.42125839, 0.41828820, 0.41531351, + 0.41233435, 0.40935081, 0.40636289, 0.40337059, 0.40037400, + 0.39737311, 0.39436796, 0.39135858, 0.38834500, 0.38532731, + 0.38230544, 0.37927949, 0.37624949, 0.37321547, 0.37017745, + 0.36713544, 0.36408952, 0.36103970, 0.35798600, 0.35492846, + 0.35186714, 0.34880206, 0.34573323, 0.34266070, 0.33958447, + 0.33650464, 0.33342120, 0.33033419, 0.32724363, 0.32414958, + 0.32105204, 0.31795108, 0.31484672, 0.31173897, 0.30862790, + 0.30551350, 0.30239585, 0.29927495, 0.29615086, 0.29302359, + 0.28989318, 0.28675964, 0.28362307, 0.28048345, 0.27734083, + 0.27419522, 0.27104670, 0.26789525, 0.26474094, 0.26158381, + 0.25842386, 0.25526115, 0.25209570, 0.24892756, 0.24575676, + 0.24258332, 0.23940729, 0.23622867, 0.23304754, 0.22986393, + 0.22667783, 0.22348931, 0.22029841, 0.21710514, 0.21390954, + 0.21071166, 0.20751151, 0.20430915, 0.20110460, 0.19789790, + 0.19468907, 0.19147816, 0.18826519, 0.18505022, 0.18183327, + 0.17861435, 0.17539354, 0.17217083, 0.16894630, 0.16571994, + 0.16249183, 0.15926196, 0.15603039, 0.15279715, 0.14956227, + 0.14632578, 0.14308774, 0.13984816, 0.13660708, 0.13336454, + 0.13012058, 0.12687522, 0.12362850, 0.12038045, 0.11713112, + 0.11388054, 0.11062872, 0.10737573, 0.10412160, 0.10086634, + 0.097609997, 0.094352618, 0.091094226, 0.087834857, 0.084574550, + 0.081313334, 0.078051247, 0.074788325, 0.071524605, 0.068260118, + 0.064994894, 0.061728980, 0.058462404, 0.055195201, 0.051927410, + 0.048659060, 0.045390189, 0.042120833, 0.038851023, 0.035580799, + 0.032310195, 0.029039243, 0.025767982, 0.022496443, 0.019224664, + 0.015952680, 0.012680525, 0.0094082337, 0.0061358409, 0.0028633832, + -0.00040910527, -0.0036815894, -0.0069540343, -0.010226404, -0.013498665, + -0.016770782, -0.020042717, -0.023314439, -0.026585912, -0.029857099, + -0.033127967, -0.036398482, -0.039668605, -0.042938303, -0.046207540, + -0.049476285, -0.052744497, -0.056012146, -0.059279196, -0.062545612, + -0.065811358, -0.069076397, -0.072340697, -0.075604223, -0.078866936, + -0.082128808, -0.085389800, -0.088649876, -0.091909006, -0.095167145, + -0.098424271, -0.10168034, -0.10493532, -0.10818918, -0.11144188, + -0.11469338, -0.11794366, -0.12119267, -0.12444039, -0.12768677, + -0.13093179, -0.13417540, -0.13741758, -0.14065829, -0.14389749, + -0.14713514, -0.15037122, -0.15360570, -0.15683852, -0.16006967, + -0.16329910, -0.16652679, -0.16975269, -0.17297678, -0.17619900, + -0.17941935, -0.18263777, -0.18585424, -0.18906870, -0.19228116, + -0.19549155, -0.19869985, -0.20190603, -0.20511003, -0.20831184, + -0.21151142, -0.21470875, -0.21790376, -0.22109644, -0.22428675, + -0.22747467, -0.23066014, -0.23384315, -0.23702365, -0.24020162, + -0.24337701, -0.24654980, -0.24971995, -0.25288740, -0.25605217, + -0.25921419, -0.26237345, -0.26552987, -0.26868346, -0.27183419, + -0.27498198, -0.27812684, -0.28126872, -0.28440759, -0.28754342, + -0.29067615, -0.29380578, -0.29693225, -0.30005556, -0.30317566, + -0.30629250, -0.30940607, -0.31251630, -0.31562322, -0.31872672, + -0.32182685, -0.32492352, -0.32801670, -0.33110636, -0.33419248, + -0.33727503, -0.34035397, -0.34342924, -0.34650084, -0.34956875, + -0.35263291, -0.35569328, -0.35874987, -0.36180258, -0.36485144, + -0.36789638, -0.37093741, -0.37397444, -0.37700745, -0.38003644, + -0.38306138, -0.38608220, -0.38909888, -0.39211139, -0.39511973, + -0.39812380, -0.40112361, -0.40411916, -0.40711036, -0.41009718, + -0.41307965, -0.41605768, -0.41903123, -0.42200032, -0.42496487, + -0.42792490, -0.43088034, -0.43383113, -0.43677729, -0.43971881, + -0.44265559, -0.44558764, -0.44851488, -0.45143735, -0.45435500, + -0.45726776, -0.46017563, -0.46307856, -0.46597654, -0.46886954, + -0.47175750, -0.47464043, -0.47751826, -0.48039100, -0.48325855, + -0.48612097, -0.48897815, -0.49183011, -0.49467680, -0.49751821, + -0.50035429, -0.50318497, -0.50601029, -0.50883019, -0.51164466, + -0.51445359, -0.51725709, -0.52005500, -0.52284735, -0.52563411, + -0.52841520, -0.53119069, -0.53396046, -0.53672451, -0.53948283, + -0.54223537, -0.54498214, -0.54772300, -0.55045801, -0.55318713, + -0.55591035, -0.55862761, -0.56133890, -0.56404412, -0.56674337, + -0.56943649, -0.57212353, -0.57480448, -0.57747924, -0.58014780, + -0.58281022, -0.58546633, -0.58811617, -0.59075975, -0.59339696, + -0.59602785, -0.59865236, -0.60127044, -0.60388207, -0.60648727, + -0.60908598, -0.61167812, -0.61426371, -0.61684275, -0.61941516, + -0.62198097, -0.62454009, -0.62709254, -0.62963831, -0.63217729, + -0.63470948, -0.63723493, -0.63975352, -0.64226526, -0.64477009, + -0.64726806, -0.64975911, -0.65224314, -0.65472025, -0.65719032, + -0.65965337, -0.66210932, -0.66455823, -0.66700000, -0.66943461, + -0.67186207, -0.67428231, -0.67669535, -0.67910111, -0.68149966, + -0.68389088, -0.68627477, -0.68865126, -0.69102043, -0.69338220, + -0.69573659, -0.69808346, -0.70042288, -0.70275480, -0.70507920, + -0.70739603, -0.70970529, -0.71200693, -0.71430099, -0.71658736, + -0.71886611, -0.72113711, -0.72340041, -0.72565591, -0.72790372, + -0.73014367, -0.73237586, -0.73460019, -0.73681659, -0.73902518, + -0.74122584, -0.74341851, -0.74560326, -0.74778003, -0.74994880, + -0.75210953, -0.75426215, -0.75640678, -0.75854325, -0.76067162, + -0.76279181, -0.76490390, -0.76700771, -0.76910341, -0.77119076, + -0.77326995, -0.77534080, -0.77740335, -0.77945763, -0.78150350, + -0.78354102, -0.78557014, -0.78759086, -0.78960317, -0.79160696, + -0.79360235, -0.79558921, -0.79756755, -0.79953730, -0.80149853, + -0.80345118, -0.80539525, -0.80733067, -0.80925739, -0.81117553, + -0.81308490, -0.81498563, -0.81687760, -0.81876087, -0.82063532, + -0.82250100, -0.82435787, -0.82620591, -0.82804507, -0.82987541, + -0.83169687, -0.83350939, -0.83531296, -0.83710766, -0.83889335, + -0.84067005, -0.84243774, -0.84419644, -0.84594607, -0.84768665, + -0.84941816, -0.85114056, -0.85285389, -0.85455805, -0.85625303, + -0.85793889, -0.85961550, -0.86128294, -0.86294121, -0.86459017, + -0.86622989, -0.86786032, -0.86948150, -0.87109333, -0.87269586, + -0.87428904, -0.87587279, -0.87744725, -0.87901229, -0.88056785, + -0.88211405, -0.88365078, -0.88517809, -0.88669586, -0.88820416, + -0.88970292, -0.89119220, -0.89267188, -0.89414203, -0.89560264, + -0.89705360, -0.89849502, -0.89992678, -0.90134889, -0.90276134, + -0.90416414, -0.90555727, -0.90694070, -0.90831441, -0.90967834, + -0.91103262, -0.91237706, -0.91371179, -0.91503674, -0.91635185, + -0.91765714, -0.91895264, -0.92023826, -0.92151409, -0.92277998, + -0.92403603, -0.92528218, -0.92651838, -0.92774469, -0.92896110, + -0.93016750, -0.93136400, -0.93255049, -0.93372697, -0.93489349, + -0.93604994, -0.93719643, -0.93833286, -0.93945926, -0.94057560, + -0.94168180, -0.94277799, -0.94386405, -0.94494003, -0.94600588, + -0.94706154, -0.94810712, -0.94914252, -0.95016778, -0.95118284, + -0.95218778, -0.95318246, -0.95416695, -0.95514119, -0.95610523, + -0.95705903, -0.95800257, -0.95893586, -0.95985889, -0.96077162, + -0.96167403, -0.96256620, -0.96344805, -0.96431959, -0.96518075, + -0.96603161, -0.96687216, -0.96770233, -0.96852213, -0.96933156, + -0.97013056, -0.97091925, -0.97169751, -0.97246534, -0.97322279, + -0.97396982, -0.97470641, -0.97543252, -0.97614825, -0.97685349, + -0.97754824, -0.97823256, -0.97890645, -0.97956979, -0.98022264, + -0.98086500, -0.98149687, -0.98211825, -0.98272908, -0.98332942, + -0.98391914, -0.98449844, -0.98506713, -0.98562527, -0.98617285, + -0.98670989, -0.98723638, -0.98775226, -0.98825759, -0.98875231, + -0.98923647, -0.98971003, -0.99017298, -0.99062532, -0.99106705, + -0.99149817, -0.99191868, -0.99232858, -0.99272782, -0.99311644, + -0.99349445, -0.99386179, -0.99421853, -0.99456459, -0.99489999, + -0.99522477, -0.99553883, -0.99584228, -0.99613506, -0.99641716, + -0.99668860, -0.99694937, -0.99719942, -0.99743885, -0.99766755, + -0.99788558, -0.99809295, -0.99828959, -0.99847561, -0.99865085, + -0.99881548, -0.99896932, -0.99911255, -0.99924499, -0.99936682, + -0.99947786, -0.99957830, -0.99966794, -0.99974692, -0.99981517, + -0.99987274, -0.99991959, -0.99995571, -0.99998116, -0.99999589, + ], &[ + 0.99999964, 0.99997288, 0.99990326, 0.99979085, 0.99963558, + 0.99943751, 0.99919659, 0.99891287, 0.99858636, 0.99821711, + 0.99780506, 0.99735034, 0.99685282, 0.99631262, 0.99572974, + 0.99510419, 0.99443603, 0.99372530, 0.99297196, 0.99217612, + 0.99133772, 0.99045694, 0.98953366, 0.98856801, 0.98756003, + 0.98650974, 0.98541719, 0.98428243, 0.98310548, 0.98188645, + 0.98062533, 0.97932225, 0.97797716, 0.97659022, 0.97516143, + 0.97369087, 0.97217858, 0.97062469, 0.96902919, 0.96739221, + 0.96571374, 0.96399397, 0.96223283, 0.96043050, 0.95858705, + 0.95670253, 0.95477700, 0.95281059, 0.95080340, 0.94875544, + 0.94666684, 0.94453770, 0.94236809, 0.94015813, 0.93790787, + 0.93561745, 0.93328691, 0.93091643, 0.92850608, 0.92605597, + 0.92356616, 0.92103678, 0.91846794, 0.91585976, 0.91321236, + 0.91052586, 0.90780038, 0.90503591, 0.90223277, 0.89939094, + 0.89651060, 0.89359182, 0.89063478, 0.88763964, 0.88460642, + 0.88153529, 0.87842643, 0.87527996, 0.87209594, 0.86887461, + 0.86561602, 0.86232042, 0.85898781, 0.85561842, 0.85221243, + 0.84876984, 0.84529096, 0.84177583, 0.83822471, 0.83463764, + 0.83101481, 0.82735640, 0.82366252, 0.81993335, 0.81616908, + 0.81236988, 0.80853581, 0.80466717, 0.80076402, 0.79682660, + 0.79285502, 0.78884947, 0.78481019, 0.78073722, 0.77663082, + 0.77249116, 0.76831841, 0.76411277, 0.75987434, 0.75560343, + 0.75130010, 0.74696463, 0.74259710, 0.73819780, 0.73376691, + 0.72930455, 0.72481096, 0.72028631, 0.71573079, 0.71114463, + 0.70652801, 0.70188117, 0.69720417, 0.69249737, 0.68776089, + 0.68299496, 0.67819971, 0.67337549, 0.66852236, 0.66364062, + 0.65873051, 0.65379208, 0.64882571, 0.64383155, 0.63880974, + 0.63376063, 0.62868434, 0.62358117, 0.61845124, 0.61329484, + 0.60811216, 0.60290343, 0.59766883, 0.59240872, 0.58712316, + 0.58181250, 0.57647687, 0.57111657, 0.56573176, 0.56032276, + 0.55488980, 0.54943299, 0.54395270, 0.53844911, 0.53292239, + 0.52737290, 0.52180082, 0.51620632, 0.51058978, 0.50495136, + 0.49929130, 0.49360985, 0.48790723, 0.48218375, 0.47643960, + 0.47067502, 0.46489030, 0.45908567, 0.45326138, 0.44741765, + 0.44155475, 0.43567297, 0.42977250, 0.42385364, 0.41791660, + 0.41196167, 0.40598908, 0.39999911, 0.39399201, 0.38796803, + 0.38192743, 0.37587047, 0.36979741, 0.36370850, 0.35760403, + 0.35148421, 0.34534934, 0.33919969, 0.33303553, 0.32685706, + 0.32066461, 0.31445843, 0.30823877, 0.30200592, 0.29576012, + 0.28950164, 0.28323078, 0.27694780, 0.27065292, 0.26434645, + 0.25802869, 0.25169984, 0.24536023, 0.23901010, 0.23264973, + 0.22627939, 0.21989937, 0.21350993, 0.20711134, 0.20070387, + 0.19428782, 0.18786344, 0.18143101, 0.17499080, 0.16854310, + 0.16208819, 0.15562633, 0.14915779, 0.14268288, 0.13620184, + 0.12971498, 0.12322257, 0.11672486, 0.11022217, 0.10371475, + 0.097202882, 0.090686858, 0.084166944, 0.077643424, 0.071116582, + 0.064586692, 0.058054037, 0.051518895, 0.044981543, 0.038442269, + 0.031901345, 0.025359053, 0.018815678, 0.012271495, 0.0057267868, + -0.00081816671, -0.0073630852, -0.013907688, -0.020451695, -0.026994826, + -0.033536803, -0.040077340, -0.046616159, -0.053152986, -0.059687532, + -0.066219524, -0.072748676, -0.079274714, -0.085797355, -0.092316322, + -0.098831341, -0.10534211, -0.11184838, -0.11834986, -0.12484626, + -0.13133731, -0.13782275, -0.14430228, -0.15077563, -0.15724251, + -0.16370267, -0.17015581, -0.17660165, -0.18303993, -0.18947038, + -0.19589271, -0.20230664, -0.20871192, -0.21510825, -0.22149536, + -0.22787298, -0.23424086, -0.24059868, -0.24694622, -0.25328314, + -0.25960925, -0.26592422, -0.27222782, -0.27851975, -0.28479972, + -0.29106751, -0.29732284, -0.30356544, -0.30979502, -0.31601134, + -0.32221413, -0.32840309, -0.33457801, -0.34073856, -0.34688455, + -0.35301566, -0.35913166, -0.36523229, -0.37131724, -0.37738630, + -0.38343921, -0.38947567, -0.39549544, -0.40149832, -0.40748394, + -0.41345215, -0.41940263, -0.42533514, -0.43124944, -0.43714526, + -0.44302234, -0.44888046, -0.45471936, -0.46053877, -0.46633846, + -0.47211814, -0.47787762, -0.48361665, -0.48933494, -0.49503228, + -0.50070840, -0.50636309, -0.51199609, -0.51760709, -0.52319598, + -0.52876246, -0.53430629, -0.53982723, -0.54532504, -0.55079949, + -0.55625033, -0.56167740, -0.56708032, -0.57245898, -0.57781315, + -0.58314258, -0.58844697, -0.59372622, -0.59897995, -0.60420811, + -0.60941035, -0.61458647, -0.61973625, -0.62485951, -0.62995601, + -0.63502556, -0.64006782, -0.64508271, -0.65007001, -0.65502942, + -0.65996075, -0.66486382, -0.66973841, -0.67458433, -0.67940134, + -0.68418926, -0.68894786, -0.69367695, -0.69837630, -0.70304573, + -0.70768511, -0.71229410, -0.71687263, -0.72142041, -0.72593731, + -0.73042315, -0.73487765, -0.73930067, -0.74369204, -0.74805158, + -0.75237900, -0.75667429, -0.76093709, -0.76516730, -0.76936477, + -0.77352923, -0.77766061, -0.78175867, -0.78582323, -0.78985411, + -0.79385114, -0.79781419, -0.80174309, -0.80563760, -0.80949765, + -0.81332302, -0.81711352, -0.82086903, -0.82458937, -0.82827437, + -0.83192390, -0.83553779, -0.83911592, -0.84265804, -0.84616417, + -0.84963393, -0.85306740, -0.85646427, -0.85982448, -0.86314780, + -0.86643422, -0.86968350, -0.87289548, -0.87607014, -0.87920725, + -0.88230664, -0.88536829, -0.88839203, -0.89137769, -0.89432514, + -0.89723432, -0.90010506, -0.90293723, -0.90573072, -0.90848541, + -0.91120118, -0.91387796, -0.91651553, -0.91911387, -0.92167282, + -0.92419231, -0.92667222, -0.92911243, -0.93151283, -0.93387336, + -0.93619382, -0.93847424, -0.94071442, -0.94291431, -0.94507378, + -0.94719279, -0.94927126, -0.95130903, -0.95330608, -0.95526224, + -0.95717752, -0.95905179, -0.96088499, -0.96267700, -0.96442777, + -0.96613729, -0.96780539, -0.96943200, -0.97101706, -0.97256058, + -0.97406244, -0.97552258, -0.97694093, -0.97831738, -0.97965199, + -0.98094457, -0.98219514, -0.98340368, -0.98457009, -0.98569429, + -0.98677629, -0.98781598, -0.98881340, -0.98976845, -0.99068111, + -0.99155134, -0.99237907, -0.99316430, -0.99390697, -0.99460709, + -0.99526459, -0.99587947, -0.99645168, -0.99698120, -0.99746799, + -0.99791211, -0.99831343, -0.99867201, -0.99898779, -0.99926084, + -0.99949104, -0.99967843, -0.99982297, -0.99992472, -0.99998361, + ], &[ + 0.99999869, 0.99989158, 0.99961317, 0.99916345, 0.99854255, + 0.99775058, 0.99678761, 0.99565387, 0.99434954, 0.99287480, + 0.99122995, 0.98941529, 0.98743105, 0.98527765, 0.98295540, + 0.98046476, 0.97780609, 0.97497988, 0.97198665, 0.96882683, + 0.96550101, 0.96200979, 0.95835376, 0.95453346, 0.95054960, + 0.94640291, 0.94209403, 0.93762374, 0.93299282, 0.92820197, + 0.92325211, 0.91814411, 0.91287869, 0.90745693, 0.90187967, + 0.89614785, 0.89026248, 0.88422459, 0.87803519, 0.87169534, + 0.86520612, 0.85856867, 0.85178405, 0.84485358, 0.83777827, + 0.83055943, 0.82319832, 0.81569612, 0.80805415, 0.80027372, + 0.79235619, 0.78430289, 0.77611518, 0.76779449, 0.75934225, + 0.75075996, 0.74204898, 0.73321080, 0.72424710, 0.71515924, + 0.70594883, 0.69661748, 0.68716675, 0.67759830, 0.66791373, + 0.65811473, 0.64820296, 0.63818014, 0.62804794, 0.61780810, + 0.60746247, 0.59701276, 0.58646071, 0.57580817, 0.56505698, + 0.55420899, 0.54326600, 0.53222996, 0.52110273, 0.50988621, + 0.49858227, 0.48719296, 0.47572014, 0.46416581, 0.45253196, + 0.44082057, 0.42903364, 0.41717321, 0.40524128, 0.39323992, + 0.38117120, 0.36903715, 0.35683987, 0.34458145, 0.33226398, + 0.31988961, 0.30746040, 0.29497850, 0.28244606, 0.26986524, + 0.25723818, 0.24456702, 0.23185398, 0.21910121, 0.20631088, + 0.19348522, 0.18062639, 0.16773662, 0.15481812, 0.14187308, + 0.12890373, 0.11591230, 0.10290100, 0.089872077, 0.076827750, + 0.063770257, 0.050701842, 0.037624735, 0.024541186, 0.011453429, + -0.0016362892, -0.014725727, -0.027812643, -0.040894791, -0.053969935, + -0.067035832, -0.080090240, -0.093130924, -0.10615565, -0.11916219, + -0.13214831, -0.14511178, -0.15805040, -0.17096193, -0.18384418, + -0.19669491, -0.20951195, -0.22229309, -0.23503613, -0.24773891, + -0.26039925, -0.27301496, -0.28558388, -0.29810387, -0.31057280, + -0.32298848, -0.33534884, -0.34765175, -0.35989508, -0.37207675, + -0.38419467, -0.39624676, -0.40823093, -0.42014518, -0.43198743, + -0.44375566, -0.45544785, -0.46706200, -0.47859612, -0.49004826, + -0.50141639, -0.51269865, -0.52389306, -0.53499764, -0.54601061, + -0.55693001, -0.56775403, -0.57848072, -0.58910829, -0.59963489, + -0.61005878, -0.62037814, -0.63059121, -0.64069623, -0.65069145, + -0.66057515, -0.67034572, -0.68000144, -0.68954057, -0.69896162, + -0.70826286, -0.71744281, -0.72649974, -0.73543227, -0.74423873, + -0.75291771, -0.76146764, -0.76988715, -0.77817470, -0.78632891, + -0.79434842, -0.80223179, -0.80997771, -0.81758487, -0.82505190, + -0.83237761, -0.83956063, -0.84659988, -0.85349399, -0.86024189, + -0.86684239, -0.87329435, -0.87959671, -0.88574833, -0.89174819, + -0.89759529, -0.90328854, -0.90882701, -0.91420978, -0.91943592, + -0.92450452, -0.92941469, -0.93416560, -0.93875647, -0.94318646, + -0.94745487, -0.95156091, -0.95550388, -0.95928317, -0.96289814, + -0.96634805, -0.96963239, -0.97275060, -0.97570217, -0.97848648, + -0.98110318, -0.98355180, -0.98583186, -0.98794299, -0.98988485, + -0.99165714, -0.99325943, -0.99469161, -0.99595332, -0.99704438, + -0.99796462, -0.99871385, -0.99929196, -0.99969882, -0.99993443, + ], &[ + 0.99999464, 0.99956632, 0.99845290, 0.99665523, 0.99417448, + 0.99101239, 0.98717111, 0.98265326, 0.97746199, 0.97160077, + 0.96507365, 0.95788515, 0.95004016, 0.94154406, 0.93240267, + 0.92262226, 0.91220951, 0.90117162, 0.88951606, 0.87725091, + 0.86438453, 0.85092574, 0.83688372, 0.82226819, 0.80708915, + 0.79135692, 0.77508235, 0.75827658, 0.74095112, 0.72311783, + 0.70478898, 0.68597710, 0.66669506, 0.64695615, 0.62677377, + 0.60616189, 0.58513457, 0.56370622, 0.54189157, 0.51970547, + 0.49716324, 0.47428027, 0.45107225, 0.42755505, 0.40374488, + 0.37965798, 0.35531086, 0.33072025, 0.30590299, 0.28087607, + 0.25565663, 0.23026201, 0.20470956, 0.17901683, 0.15320139, + 0.12728097, 0.10127331, 0.075196236, 0.049067631, 0.022905400, + -0.0032725304, -0.029448219, -0.055603724, -0.081721120, -0.10778251, + -0.13377003, -0.15966587, -0.18545228, -0.21111161, -0.23662624, + -0.26197869, -0.28715160, -0.31212771, -0.33688989, -0.36142120, + -0.38570482, -0.40972409, -0.43346253, -0.45690393, -0.48003218, + -0.50283146, -0.52528608, -0.54738069, -0.56910020, -0.59042966, + -0.61135447, -0.63186026, -0.65193301, -0.67155898, -0.69072473, + -0.70941705, -0.72762316, -0.74533063, -0.76252723, -0.77920127, + -0.79534131, -0.81093621, -0.82597536, -0.84044844, -0.85434550, + -0.86765707, -0.88037395, -0.89248747, -0.90398932, -0.91487163, + -0.92512697, -0.93474823, -0.94372886, -0.95206273, -0.95974404, + -0.96676767, -0.97312868, -0.97882277, -0.98384601, -0.98819500, + -0.99186671, -0.99485862, -0.99716878, -0.99879545, -0.99973762, + ] +]; +pub static mut mode48000_960_120: OpusCustomMode = OpusCustomMode { + Fs: 48000, + overlap: 120, + nbEBands: 21, + effEBands: 21, + preemph: [0.85000610f32, 0.0000000f32, 1.0000000f32, 1.0000000f32], + eBands: eband5ms.as_ptr(), + maxLM: 3, + nbShortMdcts: 8, + shortMdctSize: 120, + nbAllocVectors: 11, + allocVectors: band_allocation.as_ptr(), + logN: logN400.as_ptr(), + window: window120.as_ptr(), + mdct: mdct_lookup { + n: 1920, + maxshift: 3, + kfft: [ + &fft_state48000_960_0, + &fft_state48000_960_1, + &fft_state48000_960_2, + &fft_state48000_960_3, + ], + trig: &mdct_twiddles960, + }, + cache: PulseCache { + size: 392, + index: cache_index50.as_ptr(), + bits: cache_bits50.as_ptr(), + caps: cache_caps50.as_ptr(), + }, +}; +pub static mut static_mode_list: [*const OpusCustomMode; 1] = + unsafe { [&mode48000_960_120 as *const OpusCustomMode] }; + +use super::arch_h::opus_val16; +use super::{band_allocation, eband5ms}; +use crate::celt::kiss_fft::{kiss_fft_state, kiss_twiddle_cpx}; +use crate::celt::mdct::mdct_lookup; +use crate::celt::modes::{OpusCustomMode, PulseCache}; diff --git a/vendor/unsafe-libopus/src/celt/pitch.rs b/vendor/unsafe-libopus/src/celt/pitch.rs new file mode 100644 index 00000000..00f987a9 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/pitch.rs @@ -0,0 +1,600 @@ +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub type celt_sig = f32; + pub const Q15ONE: f32 = 1.0f32; +} +pub mod stddef_h { + pub const NULL: i32 = 0; +} +pub use self::arch_h::{celt_sig, opus_val16, opus_val32, Q15ONE}; +pub use self::stddef_h::NULL; +use crate::celt::celt_lpc::{_celt_autocorr, _celt_lpc}; +use crate::celt::entcode::celt_udiv; +use crate::celt::mathops::celt_sqrt; + +#[inline] +pub unsafe fn dual_inner_prod_c( + x: *const opus_val16, + y01: *const opus_val16, + y02: *const opus_val16, + N: i32, + xy1: *mut opus_val32, + xy2: *mut opus_val32, +) { + let mut i: i32 = 0; + let mut xy01: opus_val32 = 0 as opus_val32; + let mut xy02: opus_val32 = 0 as opus_val32; + i = 0; + while i < N { + xy01 = xy01 + *x.offset(i as isize) * *y01.offset(i as isize); + xy02 = xy02 + *x.offset(i as isize) * *y02.offset(i as isize); + i += 1; + } + *xy1 = xy01; + *xy2 = xy02; +} +#[inline] +pub unsafe fn xcorr_kernel_c( + mut x: *const opus_val16, + mut y: *const opus_val16, + sum: *mut opus_val32, + len: i32, +) { + let mut j: i32 = 0; + let mut y_0: opus_val16 = 0.; + let mut y_1: opus_val16 = 0.; + let mut y_2: opus_val16 = 0.; + let mut y_3: opus_val16 = 0.; + assert!(len >= 3); + y_3 = 0 as opus_val16; + let fresh0 = y; + y = y.offset(1); + y_0 = *fresh0; + let fresh1 = y; + y = y.offset(1); + y_1 = *fresh1; + let fresh2 = y; + y = y.offset(1); + y_2 = *fresh2; + j = 0; + while j < len - 3 { + let mut tmp: opus_val16 = 0.; + let fresh3 = x; + x = x.offset(1); + tmp = *fresh3; + let fresh4 = y; + y = y.offset(1); + y_3 = *fresh4; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp * y_0; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp * y_1; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp * y_2; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp * y_3; + let fresh5 = x; + x = x.offset(1); + tmp = *fresh5; + let fresh6 = y; + y = y.offset(1); + y_0 = *fresh6; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp * y_1; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp * y_2; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp * y_3; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp * y_0; + let fresh7 = x; + x = x.offset(1); + tmp = *fresh7; + let fresh8 = y; + y = y.offset(1); + y_1 = *fresh8; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp * y_2; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp * y_3; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp * y_0; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp * y_1; + let fresh9 = x; + x = x.offset(1); + tmp = *fresh9; + let fresh10 = y; + y = y.offset(1); + y_2 = *fresh10; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp * y_3; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp * y_0; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp * y_1; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp * y_2; + j += 4; + } + let fresh11 = j; + j = j + 1; + if fresh11 < len { + let fresh12 = x; + x = x.offset(1); + let tmp_0: opus_val16 = *fresh12; + let fresh13 = y; + y = y.offset(1); + y_3 = *fresh13; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp_0 * y_0; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp_0 * y_1; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp_0 * y_2; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp_0 * y_3; + } + let fresh14 = j; + j = j + 1; + if fresh14 < len { + let fresh15 = x; + x = x.offset(1); + let tmp_1: opus_val16 = *fresh15; + let fresh16 = y; + y = y.offset(1); + y_0 = *fresh16; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp_1 * y_1; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp_1 * y_2; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp_1 * y_3; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp_1 * y_0; + } + if j < len { + let fresh17 = x; + x = x.offset(1); + let tmp_2: opus_val16 = *fresh17; + let fresh18 = y; + y = y.offset(1); + y_1 = *fresh18; + *sum.offset(0 as isize) = *sum.offset(0 as isize) + tmp_2 * y_2; + *sum.offset(1 as isize) = *sum.offset(1 as isize) + tmp_2 * y_3; + *sum.offset(2 as isize) = *sum.offset(2 as isize) + tmp_2 * y_0; + *sum.offset(3 as isize) = *sum.offset(3 as isize) + tmp_2 * y_1; + } +} +#[inline] +pub unsafe fn celt_inner_prod_c(x: *const opus_val16, y: *const opus_val16, N: i32) -> opus_val32 { + let mut i: i32 = 0; + let mut xy: opus_val32 = 0 as opus_val32; + i = 0; + while i < N { + xy = xy + *x.offset(i as isize) * *y.offset(i as isize); + i += 1; + } + return xy; +} + +unsafe fn find_best_pitch( + xcorr: *mut opus_val32, + y: *mut opus_val16, + len: i32, + max_pitch: i32, + best_pitch: *mut i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut Syy: opus_val32 = 1 as opus_val32; + let mut best_num: [opus_val16; 2] = [0.; 2]; + let mut best_den: [opus_val32; 2] = [0.; 2]; + best_num[0 as usize] = -1 as opus_val16; + best_num[1 as usize] = -1 as opus_val16; + best_den[0 as usize] = 0 as opus_val32; + best_den[1 as usize] = 0 as opus_val32; + *best_pitch.offset(0 as isize) = 0; + *best_pitch.offset(1 as isize) = 1; + j = 0; + while j < len { + Syy = Syy + *y.offset(j as isize) * *y.offset(j as isize); + j += 1; + } + i = 0; + while i < max_pitch { + if *xcorr.offset(i as isize) > 0 as f32 { + let mut num: opus_val16 = 0.; + let mut xcorr16: opus_val32 = 0.; + xcorr16 = *xcorr.offset(i as isize); + xcorr16 *= 1e-12f32; + num = xcorr16 * xcorr16; + if num * best_den[1 as usize] > best_num[1 as usize] * Syy { + if num * best_den[0 as usize] > best_num[0 as usize] * Syy { + best_num[1 as usize] = best_num[0 as usize]; + best_den[1 as usize] = best_den[0 as usize]; + *best_pitch.offset(1 as isize) = *best_pitch.offset(0 as isize); + best_num[0 as usize] = num; + best_den[0 as usize] = Syy; + *best_pitch.offset(0 as isize) = i; + } else { + best_num[1 as usize] = num; + best_den[1 as usize] = Syy; + *best_pitch.offset(1 as isize) = i; + } + } + } + Syy += *y.offset((i + len) as isize) * *y.offset((i + len) as isize) + - *y.offset(i as isize) * *y.offset(i as isize); + Syy = if 1 as f32 > Syy { 1 as f32 } else { Syy }; + i += 1; + } +} +unsafe fn celt_fir5(x: *mut opus_val16, num: *const opus_val16, N: i32) { + let mut i: i32 = 0; + let mut num0: opus_val16 = 0.; + let mut num1: opus_val16 = 0.; + let mut num2: opus_val16 = 0.; + let mut num3: opus_val16 = 0.; + let mut num4: opus_val16 = 0.; + let mut mem0: opus_val32 = 0.; + let mut mem1: opus_val32 = 0.; + let mut mem2: opus_val32 = 0.; + let mut mem3: opus_val32 = 0.; + let mut mem4: opus_val32 = 0.; + num0 = *num.offset(0 as isize); + num1 = *num.offset(1 as isize); + num2 = *num.offset(2 as isize); + num3 = *num.offset(3 as isize); + num4 = *num.offset(4 as isize); + mem0 = 0 as opus_val32; + mem1 = 0 as opus_val32; + mem2 = 0 as opus_val32; + mem3 = 0 as opus_val32; + mem4 = 0 as opus_val32; + i = 0; + while i < N { + let mut sum: opus_val32 = *x.offset(i as isize); + sum = sum + num0 * mem0; + sum = sum + num1 * mem1; + sum = sum + num2 * mem2; + sum = sum + num3 * mem3; + sum = sum + num4 * mem4; + mem4 = mem3; + mem3 = mem2; + mem2 = mem1; + mem1 = mem0; + mem0 = *x.offset(i as isize); + *x.offset(i as isize) = sum; + i += 1; + } +} +pub unsafe fn pitch_downsample( + x: *mut *mut celt_sig, + x_lp: *mut opus_val16, + len: i32, + C: i32, + arch: i32, +) { + let mut i: i32 = 0; + let mut ac: [opus_val32; 5] = [0.; 5]; + let mut tmp: opus_val16 = Q15ONE; + let mut lpc: [opus_val16; 4] = [0.; 4]; + let mut lpc2: [opus_val16; 5] = [0.; 5]; + let c1: opus_val16 = 0.8f32; + i = 1; + while i < len >> 1 { + *x_lp.offset(i as isize) = 0.5f32 + * (0.5f32 + * (*(*x.offset(0 as isize)).offset((2 * i - 1) as isize) + + *(*x.offset(0 as isize)).offset((2 * i + 1) as isize)) + + *(*x.offset(0 as isize)).offset((2 * i) as isize)); + i += 1; + } + *x_lp.offset(0 as isize) = 0.5f32 + * (0.5f32 * *(*x.offset(0 as isize)).offset(1 as isize) + + *(*x.offset(0 as isize)).offset(0 as isize)); + if C == 2 { + i = 1; + while i < len >> 1 { + let ref mut fresh19 = *x_lp.offset(i as isize); + *fresh19 += 0.5f32 + * (0.5f32 + * (*(*x.offset(1 as isize)).offset((2 * i - 1) as isize) + + *(*x.offset(1 as isize)).offset((2 * i + 1) as isize)) + + *(*x.offset(1 as isize)).offset((2 * i) as isize)); + i += 1; + } + let ref mut fresh20 = *x_lp.offset(0 as isize); + *fresh20 += 0.5f32 + * (0.5f32 * *(*x.offset(1 as isize)).offset(1 as isize) + + *(*x.offset(1 as isize)).offset(0 as isize)); + } + _celt_autocorr( + x_lp, + ac.as_mut_ptr(), + NULL as *const opus_val16, + 0, + 4, + len >> 1, + arch, + ); + ac[0 as usize] *= 1.0001f32; + i = 1; + while i <= 4 { + ac[i as usize] -= ac[i as usize] * (0.008f32 * i as f32) * (0.008f32 * i as f32); + i += 1; + } + _celt_lpc(lpc.as_mut_ptr(), ac.as_mut_ptr(), 4); + i = 0; + while i < 4 { + tmp = 0.9f32 * tmp; + lpc[i as usize] = lpc[i as usize] * tmp; + i += 1; + } + lpc2[0 as usize] = lpc[0 as usize] + 0.8f32; + lpc2[1 as usize] = lpc[1 as usize] + c1 * lpc[0 as usize]; + lpc2[2 as usize] = lpc[2 as usize] + c1 * lpc[1 as usize]; + lpc2[3 as usize] = lpc[3 as usize] + c1 * lpc[2 as usize]; + lpc2[4 as usize] = c1 * lpc[3 as usize]; + celt_fir5(x_lp, lpc2.as_mut_ptr(), len >> 1); +} +pub unsafe fn celt_pitch_xcorr_c( + mut _x: *const opus_val16, + mut _y: *const opus_val16, + xcorr: *mut opus_val32, + len: i32, + max_pitch: i32, + _arch: i32, +) { + let mut i: i32 = 0; + assert!(max_pitch > 0); + i = 0; + while i < max_pitch - 3 { + let mut sum: [opus_val32; 4] = [ + 0 as opus_val32, + 0 as opus_val32, + 0 as opus_val32, + 0 as opus_val32, + ]; + xcorr_kernel_c(_x, _y.offset(i as isize), sum.as_mut_ptr(), len); + *xcorr.offset(i as isize) = sum[0 as usize]; + *xcorr.offset((i + 1) as isize) = sum[1 as usize]; + *xcorr.offset((i + 2) as isize) = sum[2 as usize]; + *xcorr.offset((i + 3) as isize) = sum[3 as usize]; + i += 4; + } + while i < max_pitch { + let mut sum_0: opus_val32 = 0.; + sum_0 = celt_inner_prod_c(_x, _y.offset(i as isize), len); + *xcorr.offset(i as isize) = sum_0; + i += 1; + } +} +pub unsafe fn pitch_search( + x_lp: *const opus_val16, + y: *mut opus_val16, + len: i32, + max_pitch: i32, + pitch: *mut i32, + arch: i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut lag: i32 = 0; + let mut best_pitch: [i32; 2] = [0, 0]; + let mut offset: i32 = 0; + assert!(len > 0); + assert!(max_pitch > 0); + lag = len + max_pitch; + let vla = (len >> 2) as usize; + let mut x_lp4: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = (lag >> 2) as usize; + let mut y_lp4: Vec = ::std::vec::from_elem(0., vla_0); + let vla_1 = (max_pitch >> 1) as usize; + let mut xcorr: Vec = ::std::vec::from_elem(0., vla_1); + j = 0; + while j < len >> 2 { + *x_lp4.as_mut_ptr().offset(j as isize) = *x_lp.offset((2 * j) as isize); + j += 1; + } + j = 0; + while j < lag >> 2 { + *y_lp4.as_mut_ptr().offset(j as isize) = *y.offset((2 * j) as isize); + j += 1; + } + celt_pitch_xcorr_c( + x_lp4.as_mut_ptr(), + y_lp4.as_mut_ptr(), + xcorr.as_mut_ptr(), + len >> 2, + max_pitch >> 2, + arch, + ); + find_best_pitch( + xcorr.as_mut_ptr(), + y_lp4.as_mut_ptr(), + len >> 2, + max_pitch >> 2, + best_pitch.as_mut_ptr(), + ); + i = 0; + while i < max_pitch >> 1 { + let mut sum: opus_val32 = 0.; + *xcorr.as_mut_ptr().offset(i as isize) = 0 as opus_val32; + if !((i - 2 * best_pitch[0 as usize]).abs() > 2 + && (i - 2 * best_pitch[1 as usize]).abs() > 2) + { + sum = celt_inner_prod_c(x_lp, y.offset(i as isize), len >> 1); + *xcorr.as_mut_ptr().offset(i as isize) = if -1 as f32 > sum { -1 as f32 } else { sum }; + } + i += 1; + } + find_best_pitch( + xcorr.as_mut_ptr(), + y, + len >> 1, + max_pitch >> 1, + best_pitch.as_mut_ptr(), + ); + if best_pitch[0 as usize] > 0 && best_pitch[0 as usize] < (max_pitch >> 1) - 1 { + let mut a: opus_val32 = 0.; + let mut b: opus_val32 = 0.; + let mut c: opus_val32 = 0.; + a = *xcorr + .as_mut_ptr() + .offset((best_pitch[0 as usize] - 1) as isize); + b = *xcorr.as_mut_ptr().offset(best_pitch[0 as usize] as isize); + c = *xcorr + .as_mut_ptr() + .offset((best_pitch[0 as usize] + 1) as isize); + if c - a > 0.7f32 * (b - a) { + offset = 1; + } else if a - c > 0.7f32 * (b - c) { + offset = -1; + } else { + offset = 0; + } + } else { + offset = 0; + } + *pitch = 2 * best_pitch[0 as usize] - offset; +} +unsafe fn compute_pitch_gain(xy: opus_val32, xx: opus_val32, yy: opus_val32) -> opus_val16 { + return xy / celt_sqrt(1 as f32 + xx * yy); +} +static mut second_check: [i32; 16] = [0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2]; +pub unsafe fn remove_doubling( + mut x: *mut opus_val16, + mut maxperiod: i32, + mut minperiod: i32, + mut N: i32, + T0_: *mut i32, + mut prev_period: i32, + prev_gain: opus_val16, + _arch: i32, +) -> opus_val16 { + let mut k: i32 = 0; + let mut i: i32 = 0; + let mut T: i32 = 0; + let mut T0: i32 = 0; + let mut g: opus_val16 = 0.; + let mut g0: opus_val16 = 0.; + let mut pg: opus_val16 = 0.; + let mut xy: opus_val32 = 0.; + let mut xx: opus_val32 = 0.; + let mut yy: opus_val32 = 0.; + let mut xy2: opus_val32 = 0.; + let mut xcorr: [opus_val32; 3] = [0.; 3]; + let mut best_xy: opus_val32 = 0.; + let mut best_yy: opus_val32 = 0.; + let mut offset: i32 = 0; + let mut minperiod0: i32 = 0; + minperiod0 = minperiod; + maxperiod /= 2; + minperiod /= 2; + *T0_ /= 2; + prev_period /= 2; + N /= 2; + x = x.offset(maxperiod as isize); + if *T0_ >= maxperiod { + *T0_ = maxperiod - 1; + } + T0 = *T0_; + T = T0; + let vla = (maxperiod + 1) as usize; + let mut yy_lookup: Vec = ::std::vec::from_elem(0., vla); + dual_inner_prod_c(x, x, x.offset(-(T0 as isize)), N, &mut xx, &mut xy); + *yy_lookup.as_mut_ptr().offset(0 as isize) = xx; + yy = xx; + i = 1; + while i <= maxperiod { + yy = yy + *x.offset(-i as isize) * *x.offset(-i as isize) + - *x.offset((N - i) as isize) * *x.offset((N - i) as isize); + *yy_lookup.as_mut_ptr().offset(i as isize) = if 0 as f32 > yy { 0 as f32 } else { yy }; + i += 1; + } + yy = *yy_lookup.as_mut_ptr().offset(T0 as isize); + best_xy = xy; + best_yy = yy; + g0 = compute_pitch_gain(xy, xx, yy); + g = g0; + k = 2; + while k <= 15 { + let mut T1: i32 = 0; + let mut T1b: i32 = 0; + let mut g1: opus_val16 = 0.; + let mut cont: opus_val16 = 0 as opus_val16; + let mut thresh: opus_val16 = 0.; + T1 = celt_udiv((2 * T0 + k) as u32, (2 * k) as u32) as i32; + if T1 < minperiod { + break; + } + if k == 2 { + if T1 + T0 > maxperiod { + T1b = T0; + } else { + T1b = T0 + T1; + } + } else { + T1b = celt_udiv( + (2 * second_check[k as usize] * T0 + k) as u32, + (2 * k) as u32, + ) as i32; + } + dual_inner_prod_c( + x, + &mut *x.offset(-T1 as isize), + &mut *x.offset(-T1b as isize), + N, + &mut xy, + &mut xy2, + ); + xy = 0.5f32 * (xy + xy2); + yy = 0.5f32 + * (*yy_lookup.as_mut_ptr().offset(T1 as isize) + + *yy_lookup.as_mut_ptr().offset(T1b as isize)); + g1 = compute_pitch_gain(xy, xx, yy); + if (T1 - prev_period).abs() <= 1 { + cont = prev_gain; + } else if (T1 - prev_period).abs() <= 2 && 5 * k * k < T0 { + cont = 0.5f32 * prev_gain; + } else { + cont = 0 as opus_val16; + } + thresh = if 0.3f32 > 0.7f32 * g0 - cont { + 0.3f32 + } else { + 0.7f32 * g0 - cont + }; + if T1 < 3 * minperiod { + thresh = if 0.4f32 > 0.85f32 * g0 - cont { + 0.4f32 + } else { + 0.85f32 * g0 - cont + }; + } else if T1 < 2 * minperiod { + thresh = if 0.5f32 > 0.9f32 * g0 - cont { + 0.5f32 + } else { + 0.9f32 * g0 - cont + }; + } + if g1 > thresh { + best_xy = xy; + best_yy = yy; + T = T1; + g = g1; + } + k += 1; + } + best_xy = if 0 as f32 > best_xy { + 0 as f32 + } else { + best_xy + }; + if best_yy <= best_xy { + pg = Q15ONE; + } else { + pg = best_xy / (best_yy + 1 as f32); + } + k = 0; + while k < 3 { + xcorr[k as usize] = celt_inner_prod_c(x, x.offset(-((T + k - 1) as isize)), N); + k += 1; + } + if xcorr[2 as usize] - xcorr[0 as usize] > 0.7f32 * (xcorr[1 as usize] - xcorr[0 as usize]) { + offset = 1; + } else if xcorr[0 as usize] - xcorr[2 as usize] + > 0.7f32 * (xcorr[1 as usize] - xcorr[2 as usize]) + { + offset = -1; + } else { + offset = 0; + } + if pg > g { + pg = g; + } + *T0_ = 2 * T + offset; + if *T0_ < minperiod0 { + *T0_ = minperiod0; + } + return pg; +} diff --git a/vendor/unsafe-libopus/src/celt/quant_bands.rs b/vendor/unsafe-libopus/src/celt/quant_bands.rs new file mode 100644 index 00000000..e4c46d9d --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/quant_bands.rs @@ -0,0 +1,713 @@ +use crate::celt::entcode::{ec_ctx_saved, ec_tell, ec_tell_frac}; +use crate::celt::entdec::{ec_dec, ec_dec_bit_logp, ec_dec_bits, ec_dec_icdf}; +use crate::celt::entenc::{ec_enc, ec_enc_bit_logp, ec_enc_bits, ec_enc_icdf}; +use crate::celt::laplace::{ec_laplace_decode, ec_laplace_encode}; +use crate::celt::mathops::celt_log2; +use crate::celt::modes::OpusCustomMode; +use crate::celt::rate::MAX_FINE_BITS; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub type celt_ener = f32; +} + +pub mod stack_alloc_h { + pub const ALLOC_NONE: i32 = 1; +} +pub use self::arch_h::{celt_ener, opus_val16, opus_val32}; +pub use self::stack_alloc_h::ALLOC_NONE; + +use crate::externs::memcpy; +pub static eMeans: [opus_val16; 25] = [ + 6.437500f32, + 6.250000f32, + 5.750000f32, + 5.312500f32, + 5.062500f32, + 4.812500f32, + 4.500000f32, + 4.375000f32, + 4.875000f32, + 4.687500f32, + 4.562500f32, + 4.437500f32, + 4.875000f32, + 4.625000f32, + 4.312500f32, + 4.500000f32, + 4.375000f32, + 4.625000f32, + 4.750000f32, + 4.437500f32, + 3.750000f32, + 3.750000f32, + 3.750000f32, + 3.750000f32, + 3.750000f32, +]; +static mut pred_coef: [opus_val16; 4] = [ + (29440 as f64 / 32768.0f64) as opus_val16, + (26112 as f64 / 32768.0f64) as opus_val16, + (21248 as f64 / 32768.0f64) as opus_val16, + (16384 as f64 / 32768.0f64) as opus_val16, +]; +static mut beta_coef: [opus_val16; 4] = [ + (30147 as f64 / 32768.0f64) as opus_val16, + (22282 as f64 / 32768.0f64) as opus_val16, + (12124 as f64 / 32768.0f64) as opus_val16, + (6554 as f64 / 32768.0f64) as opus_val16, +]; +static mut beta_intra: opus_val16 = (4915 as f64 / 32768.0f64) as opus_val16; +static mut e_prob_model: [[[u8; 42]; 2]; 4] = [ + [ + [ + 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128, 64, 128, 92, 78, 92, 79, + 92, 78, 90, 79, 116, 41, 115, 40, 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, + 177, 11, + ], + [ + 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132, 55, 132, 61, 114, 70, + 96, 74, 88, 75, 88, 87, 74, 89, 66, 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, + 78, 50, + ], + ], + [ + [ + 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74, 93, 74, 109, 40, 114, 36, 117, + 34, 117, 34, 143, 17, 145, 18, 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, + 9, + ], + [ + 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91, 73, 91, 78, 89, 86, 80, 92, + 66, 93, 64, 102, 59, 103, 60, 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, + 45, + ], + ], + [ + [ + 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38, 112, 38, 124, 26, 132, 27, + 136, 19, 140, 20, 155, 14, 159, 16, 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, + 159, 10, + ], + [ + 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73, 87, 72, 92, 75, 98, 72, 105, + 58, 107, 54, 115, 52, 114, 55, 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, + 42, + ], + ], + [ + [ + 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36, 119, 33, 127, 33, 134, + 34, 139, 21, 147, 23, 152, 20, 158, 25, 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, + 150, 13, 139, 15, + ], + [ + 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72, 96, 67, 101, 73, 107, 72, + 113, 55, 118, 52, 125, 52, 118, 52, 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, + 33, 77, 40, + ], + ], +]; +static mut small_energy_icdf: [u8; 3] = [2, 1, 0]; +unsafe fn loss_distortion( + eBands: *const opus_val16, + oldEBands: *mut opus_val16, + start: i32, + end: i32, + len: i32, + C: i32, +) -> opus_val32 { + let mut c: i32 = 0; + let mut i: i32 = 0; + let mut dist: opus_val32 = 0 as opus_val32; + c = 0; + loop { + i = start; + while i < end { + let d: opus_val16 = + *eBands.offset((i + c * len) as isize) - *oldEBands.offset((i + c * len) as isize); + dist = dist + d * d; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } + return if (200 as f32) < dist { + 200 as f32 + } else { + dist + }; +} +unsafe fn quant_coarse_energy_impl( + m: *const OpusCustomMode, + start: i32, + end: i32, + eBands: *const opus_val16, + oldEBands: *mut opus_val16, + budget: i32, + mut tell: i32, + prob_model: *const u8, + error: *mut opus_val16, + enc: &mut ec_enc, + C: i32, + LM: i32, + intra: i32, + max_decay: opus_val16, + lfe: i32, +) -> i32 { + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut badness: i32 = 0; + let mut prev: [opus_val32; 2] = [0 as opus_val32, 0 as opus_val32]; + let mut coef: opus_val16 = 0.; + let mut beta: opus_val16 = 0.; + if tell + 3 <= budget { + ec_enc_bit_logp(enc, intra, 3); + } + if intra != 0 { + coef = 0 as opus_val16; + beta = beta_intra; + } else { + beta = beta_coef[LM as usize]; + coef = pred_coef[LM as usize]; + } + i = start; + while i < end { + c = 0; + loop { + let mut bits_left: i32 = 0; + let mut qi: i32 = 0; + let mut qi0: i32 = 0; + let mut q: opus_val32 = 0.; + let mut x: opus_val16 = 0.; + let mut f: opus_val32 = 0.; + let mut tmp: opus_val32 = 0.; + let mut oldE: opus_val16 = 0.; + let mut decay_bound: opus_val16 = 0.; + x = *eBands.offset((i + c * (*m).nbEBands) as isize); + oldE = if -9.0f32 > *oldEBands.offset((i + c * (*m).nbEBands) as isize) { + -9.0f32 + } else { + *oldEBands.offset((i + c * (*m).nbEBands) as isize) + }; + f = x - coef * oldE - prev[c as usize]; + qi = (0.5f32 + f).floor() as i32; + decay_bound = (if -28.0f32 > *oldEBands.offset((i + c * (*m).nbEBands) as isize) { + -28.0f32 + } else { + *oldEBands.offset((i + c * (*m).nbEBands) as isize) + }) - max_decay; + if qi < 0 && x < decay_bound { + qi += (decay_bound - x) as i32; + if qi > 0 { + qi = 0; + } + } + qi0 = qi; + tell = ec_tell(enc); + bits_left = budget - tell - 3 * C * (end - i); + if i != start && bits_left < 30 { + if bits_left < 24 { + qi = if (1) < qi { 1 } else { qi }; + } + if bits_left < 16 { + qi = if -1 > qi { -1 } else { qi }; + } + } + if lfe != 0 && i >= 2 { + qi = if qi < 0 { qi } else { 0 }; + } + if budget - tell >= 15 { + let mut pi: i32 = 0; + pi = 2 * (if i < 20 { i } else { 20 }); + ec_laplace_encode( + enc, + &mut qi, + ((*prob_model.offset(pi as isize) as i32) << 7) as u32, + (*prob_model.offset((pi + 1) as isize) as i32) << 6, + ); + } else if budget - tell >= 2 { + qi = if -1 > (if qi < 1 { qi } else { 1 }) { + -1 + } else if qi < 1 { + qi + } else { + 1 + }; + ec_enc_icdf(enc, 2 * qi ^ -((qi < 0) as i32), &small_energy_icdf, 2); + } else if budget - tell >= 1 { + qi = if (0) < qi { 0 } else { qi }; + ec_enc_bit_logp(enc, -qi, 1); + } else { + qi = -1; + } + *error.offset((i + c * (*m).nbEBands) as isize) = f - qi as f32; + badness += (qi0 - qi).abs(); + q = qi as opus_val32; + tmp = coef * oldE + prev[c as usize] + q; + *oldEBands.offset((i + c * (*m).nbEBands) as isize) = tmp; + prev[c as usize] = prev[c as usize] + q - beta * q; + c += 1; + if !(c < C) { + break; + } + } + i += 1; + } + return if lfe != 0 { 0 } else { badness }; +} +pub unsafe fn quant_coarse_energy( + m: *const OpusCustomMode, + start: i32, + end: i32, + effEnd: i32, + eBands: *const opus_val16, + oldEBands: *mut opus_val16, + budget: u32, + error: *mut opus_val16, + enc: &mut ec_enc, + C: i32, + LM: i32, + nbAvailableBytes: i32, + force_intra: i32, + delayedIntra: *mut opus_val32, + mut two_pass: i32, + loss_rate: i32, + lfe: i32, +) { + let mut intra: i32 = 0; + let mut max_decay: opus_val16 = 0.; + let mut enc_start_state = ec_ctx_saved::default(); + let mut tell: u32 = 0; + let mut badness1: i32 = 0; + let mut intra_bias: i32 = 0; + let mut new_distortion: opus_val32 = 0.; + intra = (force_intra != 0 + || two_pass == 0 + && *delayedIntra > (2 * C * (end - start)) as f32 + && nbAvailableBytes > (end - start) * C) as i32; + intra_bias = (budget as f32 * *delayedIntra * loss_rate as f32 / (C * 512) as f32) as i32; + new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, (*m).nbEBands, C); + tell = ec_tell(enc) as u32; + if tell.wrapping_add(3) > budget { + intra = 0; + two_pass = intra; + } + max_decay = 16.0f32; + if end - start > 10 { + max_decay = if max_decay < 0.125f32 * nbAvailableBytes as f32 { + max_decay + } else { + 0.125f32 * nbAvailableBytes as f32 + }; + } + if lfe != 0 { + max_decay = 3.0f32; + } + enc_start_state = enc.save(); + let vla = (C * (*m).nbEBands) as usize; + let mut oldEBands_intra: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = (C * (*m).nbEBands) as usize; + let mut error_intra: Vec = ::std::vec::from_elem(0., vla_0); + memcpy( + oldEBands_intra.as_mut_ptr() as *mut core::ffi::c_void, + oldEBands as *const core::ffi::c_void, + ((C * (*m).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * oldEBands_intra.as_mut_ptr().offset_from(oldEBands) as i64) as u64), + ); + if two_pass != 0 || intra != 0 { + badness1 = quant_coarse_energy_impl( + m, + start, + end, + eBands, + oldEBands_intra.as_mut_ptr(), + budget as i32, + tell as i32, + (e_prob_model[LM as usize][1]).as_ptr(), + error_intra.as_mut_ptr(), + enc, + C, + LM, + 1, + max_decay, + lfe, + ); + } + if intra == 0 { + let mut intra_buf: *mut u8 = 0 as *mut u8; + let mut enc_intra_state = ec_ctx_saved::default(); + let mut tell_intra: i32 = 0; + let mut nstart_bytes: u32 = 0; + let mut nintra_bytes: u32 = 0; + let mut save_bytes: u32 = 0; + let mut badness2: i32 = 0; + tell_intra = ec_tell_frac(enc) as i32; + enc_intra_state = enc.save(); + nstart_bytes = enc_start_state.offs; + nintra_bytes = enc_intra_state.offs; + intra_buf = (enc.buf.as_mut_ptr()).offset(nstart_bytes as isize); + save_bytes = nintra_bytes.wrapping_sub(nstart_bytes); + if save_bytes == 0 { + save_bytes = ALLOC_NONE as u32; + } + let vla_1 = save_bytes as usize; + let mut intra_bits: Vec = ::std::vec::from_elem(0, vla_1); + memcpy( + intra_bits.as_mut_ptr() as *mut core::ffi::c_void, + intra_buf as *const core::ffi::c_void, + (nintra_bytes.wrapping_sub(nstart_bytes) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * intra_bits.as_mut_ptr().offset_from(intra_buf) as i64) as u64), + ); + enc.restore(enc_start_state); + badness2 = quant_coarse_energy_impl( + m, + start, + end, + eBands, + oldEBands, + budget as i32, + tell as i32, + (e_prob_model[LM as usize][intra as usize]).as_ptr(), + error, + enc, + C, + LM, + 0, + max_decay, + lfe, + ); + if two_pass != 0 + && (badness1 < badness2 + || badness1 == badness2 && ec_tell_frac(enc) as i32 + intra_bias > tell_intra) + { + enc.restore(enc_intra_state); + memcpy( + intra_buf as *mut core::ffi::c_void, + intra_bits.as_mut_ptr() as *const core::ffi::c_void, + (nintra_bytes.wrapping_sub(nstart_bytes) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * intra_buf.offset_from(intra_bits.as_mut_ptr()) as i64) as u64, + ), + ); + memcpy( + oldEBands as *mut core::ffi::c_void, + oldEBands_intra.as_mut_ptr() as *const core::ffi::c_void, + ((C * (*m).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * oldEBands.offset_from(oldEBands_intra.as_mut_ptr()) as i64) as u64, + ), + ); + memcpy( + error as *mut core::ffi::c_void, + error_intra.as_mut_ptr() as *const core::ffi::c_void, + ((C * (*m).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * error.offset_from(error_intra.as_mut_ptr()) as i64) as u64), + ); + intra = 1; + } + } else { + memcpy( + oldEBands as *mut core::ffi::c_void, + oldEBands_intra.as_mut_ptr() as *const core::ffi::c_void, + ((C * (*m).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * oldEBands.offset_from(oldEBands_intra.as_mut_ptr()) as i64) as u64, + ), + ); + memcpy( + error as *mut core::ffi::c_void, + error_intra.as_mut_ptr() as *const core::ffi::c_void, + ((C * (*m).nbEBands) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * error.offset_from(error_intra.as_mut_ptr()) as i64) as u64), + ); + } + if intra != 0 { + *delayedIntra = new_distortion; + } else { + *delayedIntra = + pred_coef[LM as usize] * pred_coef[LM as usize] * *delayedIntra + new_distortion; + }; +} +pub unsafe fn quant_fine_energy( + m: *const OpusCustomMode, + start: i32, + end: i32, + oldEBands: *mut opus_val16, + error: *mut opus_val16, + fine_quant: *mut i32, + enc: &mut ec_enc, + C: i32, +) { + let mut i: i32 = 0; + let mut c: i32 = 0; + i = start; + while i < end { + let frac: i16 = ((1) << *fine_quant.offset(i as isize)) as i16; + if !(*fine_quant.offset(i as isize) <= 0) { + c = 0; + loop { + let mut q2: i32 = 0; + let mut offset: opus_val16 = 0.; + q2 = ((*error.offset((i + c * (*m).nbEBands) as isize) + 0.5f32) + * frac as i32 as f32) + .floor() as i32; + if q2 > frac as i32 - 1 { + q2 = frac as i32 - 1; + } + if q2 < 0 { + q2 = 0; + } + ec_enc_bits(enc, q2 as u32, *fine_quant.offset(i as isize) as u32); + offset = (q2 as f32 + 0.5f32) + * ((1) << 14 - *fine_quant.offset(i as isize)) as f32 + * (1.0f32 / 16384 as f32) + - 0.5f32; + let ref mut fresh0 = *oldEBands.offset((i + c * (*m).nbEBands) as isize); + *fresh0 += offset; + let ref mut fresh1 = *error.offset((i + c * (*m).nbEBands) as isize); + *fresh1 -= offset; + c += 1; + if !(c < C) { + break; + } + } + } + i += 1; + } +} +pub unsafe fn quant_energy_finalise( + m: *const OpusCustomMode, + start: i32, + end: i32, + oldEBands: *mut opus_val16, + error: *mut opus_val16, + fine_quant: *mut i32, + fine_priority: *mut i32, + mut bits_left: i32, + enc: &mut ec_enc, + C: i32, +) { + let mut i: i32 = 0; + let mut prio: i32 = 0; + let mut c: i32 = 0; + prio = 0; + while prio < 2 { + i = start; + while i < end && bits_left >= C { + if !(*fine_quant.offset(i as isize) >= MAX_FINE_BITS + || *fine_priority.offset(i as isize) != prio) + { + c = 0; + loop { + let mut q2: i32 = 0; + let mut offset: opus_val16 = 0.; + q2 = if *error.offset((i + c * (*m).nbEBands) as isize) < 0 as f32 { + 0 + } else { + 1 + }; + ec_enc_bits(enc, q2 as u32, 1); + offset = (q2 as f32 - 0.5f32) + * ((1) << 14 - *fine_quant.offset(i as isize) - 1) as f32 + * (1.0f32 / 16384 as f32); + let ref mut fresh2 = *oldEBands.offset((i + c * (*m).nbEBands) as isize); + *fresh2 += offset; + let ref mut fresh3 = *error.offset((i + c * (*m).nbEBands) as isize); + *fresh3 -= offset; + bits_left -= 1; + c += 1; + if !(c < C) { + break; + } + } + } + i += 1; + } + prio += 1; + } +} +pub unsafe fn unquant_coarse_energy( + m: *const OpusCustomMode, + start: i32, + end: i32, + oldEBands: *mut opus_val16, + intra: i32, + dec: &mut ec_dec, + C: i32, + LM: i32, +) { + let prob_model: *const u8 = (e_prob_model[LM as usize][intra as usize]).as_ptr(); + let mut i: i32 = 0; + let mut c: i32 = 0; + let mut prev: [opus_val32; 2] = [0 as opus_val32, 0 as opus_val32]; + let mut coef: opus_val16 = 0.; + let mut beta: opus_val16 = 0.; + let mut budget: i32 = 0; + let mut tell: i32 = 0; + if intra != 0 { + coef = 0 as opus_val16; + beta = beta_intra; + } else { + beta = beta_coef[LM as usize]; + coef = pred_coef[LM as usize]; + } + budget = ((*dec).storage).wrapping_mul(8) as i32; + i = start; + while i < end { + c = 0; + loop { + let mut qi: i32 = 0; + let mut q: opus_val32 = 0.; + let mut tmp: opus_val32 = 0.; + tell = ec_tell(dec); + if budget - tell >= 15 { + let mut pi: i32 = 0; + pi = 2 * (if i < 20 { i } else { 20 }); + qi = ec_laplace_decode( + dec, + ((*prob_model.offset(pi as isize) as i32) << 7) as u32, + (*prob_model.offset((pi + 1) as isize) as i32) << 6, + ); + } else if budget - tell >= 2 { + qi = ec_dec_icdf(dec, &small_energy_icdf, 2); + qi = qi >> 1 ^ -(qi & 1); + } else if budget - tell >= 1 { + qi = -ec_dec_bit_logp(dec, 1); + } else { + qi = -1; + } + q = qi as opus_val32; + *oldEBands.offset((i + c * (*m).nbEBands) as isize) = + if -9.0f32 > *oldEBands.offset((i + c * (*m).nbEBands) as isize) { + -9.0f32 + } else { + *oldEBands.offset((i + c * (*m).nbEBands) as isize) + }; + tmp = coef * *oldEBands.offset((i + c * (*m).nbEBands) as isize) + prev[c as usize] + q; + *oldEBands.offset((i + c * (*m).nbEBands) as isize) = tmp; + prev[c as usize] = prev[c as usize] + q - beta * q; + c += 1; + if !(c < C) { + break; + } + } + i += 1; + } +} +pub unsafe fn unquant_fine_energy( + m: *const OpusCustomMode, + start: i32, + end: i32, + oldEBands: *mut opus_val16, + fine_quant: *mut i32, + dec: &mut ec_dec, + C: i32, +) { + let mut i: i32 = 0; + let mut c: i32 = 0; + i = start; + while i < end { + if !(*fine_quant.offset(i as isize) <= 0) { + c = 0; + loop { + let mut q2: i32 = 0; + let mut offset: opus_val16 = 0.; + q2 = ec_dec_bits(dec, *fine_quant.offset(i as isize) as u32) as i32; + offset = (q2 as f32 + 0.5f32) + * ((1) << 14 - *fine_quant.offset(i as isize)) as f32 + * (1.0f32 / 16384 as f32) + - 0.5f32; + let ref mut fresh4 = *oldEBands.offset((i + c * (*m).nbEBands) as isize); + *fresh4 += offset; + c += 1; + if !(c < C) { + break; + } + } + } + i += 1; + } +} +pub unsafe fn unquant_energy_finalise( + m: *const OpusCustomMode, + start: i32, + end: i32, + oldEBands: *mut opus_val16, + fine_quant: *mut i32, + fine_priority: *mut i32, + mut bits_left: i32, + dec: &mut ec_dec, + C: i32, +) { + let mut i: i32 = 0; + let mut prio: i32 = 0; + let mut c: i32 = 0; + prio = 0; + while prio < 2 { + i = start; + while i < end && bits_left >= C { + if !(*fine_quant.offset(i as isize) >= MAX_FINE_BITS + || *fine_priority.offset(i as isize) != prio) + { + c = 0; + loop { + let mut q2: i32 = 0; + let mut offset: opus_val16 = 0.; + q2 = ec_dec_bits(dec, 1) as i32; + offset = (q2 as f32 - 0.5f32) + * ((1) << 14 - *fine_quant.offset(i as isize) - 1) as f32 + * (1.0f32 / 16384 as f32); + let ref mut fresh5 = *oldEBands.offset((i + c * (*m).nbEBands) as isize); + *fresh5 += offset; + bits_left -= 1; + c += 1; + if !(c < C) { + break; + } + } + } + i += 1; + } + prio += 1; + } +} +pub unsafe fn amp2Log2( + m: *const OpusCustomMode, + effEnd: i32, + end: i32, + bandE: *mut celt_ener, + bandLogE: *mut opus_val16, + C: i32, +) { + let mut c: i32 = 0; + let mut i: i32 = 0; + c = 0; + loop { + i = 0; + while i < effEnd { + *bandLogE.offset((i + c * (*m).nbEBands) as isize) = + celt_log2(*bandE.offset((i + c * (*m).nbEBands) as isize)) - eMeans[i as usize]; + i += 1; + } + i = effEnd; + while i < end { + *bandLogE.offset((c * (*m).nbEBands + i) as isize) = -14.0f32; + i += 1; + } + c += 1; + if !(c < C) { + break; + } + } +} diff --git a/vendor/unsafe-libopus/src/celt/rate.rs b/vendor/unsafe-libopus/src/celt/rate.rs new file mode 100644 index 00000000..38bad6c3 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/rate.rs @@ -0,0 +1,625 @@ +pub const FINE_OFFSET: i32 = 21; +pub const MAX_FINE_BITS: i32 = 8; +#[inline] +pub unsafe fn get_pulses(i: i32) -> i32 { + return if i < 8 { + i + } else { + 8 + (i & 7) << (i >> 3) - 1 + }; +} +#[inline] +pub unsafe fn bits2pulses(m: *const OpusCustomMode, band: i32, mut LM: i32, mut bits: i32) -> i32 { + let mut i: i32 = 0; + let mut lo: i32 = 0; + let mut hi: i32 = 0; + let mut cache: *const u8 = 0 as *const u8; + LM += 1; + cache = ((*m).cache.bits) + .offset(*((*m).cache.index).offset((LM * (*m).nbEBands + band) as isize) as i32 as isize); + lo = 0; + hi = *cache.offset(0 as isize) as i32; + bits -= 1; + i = 0; + while i < LOG_MAX_PSEUDO { + let mid: i32 = lo + hi + 1 >> 1; + if *cache.offset(mid as isize) as i32 >= bits { + hi = mid; + } else { + lo = mid; + } + i += 1; + } + if bits + - (if lo == 0 { + -1 + } else { + *cache.offset(lo as isize) as i32 + }) + <= *cache.offset(hi as isize) as i32 - bits + { + return lo; + } else { + return hi; + }; +} +pub const LOG_MAX_PSEUDO: i32 = 6; +#[inline] +pub unsafe fn pulses2bits(m: *const OpusCustomMode, band: i32, mut LM: i32, pulses: i32) -> i32 { + let mut cache: *const u8 = 0 as *const u8; + LM += 1; + cache = ((*m).cache.bits) + .offset(*((*m).cache.index).offset((LM * (*m).nbEBands + band) as isize) as i32 as isize); + return if pulses == 0 { + 0 + } else { + *cache.offset(pulses as isize) as i32 + 1 + }; +} +pub const QTHETA_OFFSET_TWOPHASE: i32 = 16; +pub const QTHETA_OFFSET: i32 = 4; + +use crate::celt::entcode::{celt_udiv, ec_ctx, BITRES}; +use crate::celt::entdec::{ec_dec_bit_logp, ec_dec_uint}; +use crate::celt::entenc::{ec_enc_bit_logp, ec_enc_uint}; +use crate::celt::modes::OpusCustomMode; + +static mut LOG2_FRAC_TABLE: [u8; 24] = [ + 0, 8, 13, 16, 19, 21, 23, 24, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 37, +]; +pub const ALLOC_STEPS: i32 = 6; +#[inline] +unsafe fn interp_bits2pulses( + m: *const OpusCustomMode, + start: i32, + end: i32, + skip_start: i32, + bits1: *const i32, + bits2: *const i32, + thresh: *const i32, + cap: *const i32, + mut total: i32, + mut _balance: *mut i32, + skip_rsv: i32, + intensity: *mut i32, + mut intensity_rsv: i32, + dual_stereo: *mut i32, + mut dual_stereo_rsv: i32, + bits: *mut i32, + ebits: *mut i32, + fine_priority: *mut i32, + C: i32, + LM: i32, + ec: &mut ec_ctx, + encode: i32, + prev: i32, + signalBandwidth: i32, +) -> i32 { + let mut psum: i32 = 0; + let mut lo: i32 = 0; + let mut hi: i32 = 0; + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut logM: i32 = 0; + let mut stereo: i32 = 0; + let mut codedBands: i32 = -1; + let mut alloc_floor: i32 = 0; + let mut left: i32 = 0; + let mut percoeff: i32 = 0; + let mut done: i32 = 0; + let mut balance: i32 = 0; + alloc_floor = C << BITRES; + stereo = (C > 1) as i32; + logM = LM << BITRES; + lo = 0; + hi = (1) << ALLOC_STEPS; + i = 0; + while i < ALLOC_STEPS { + let mid: i32 = lo + hi >> 1; + psum = 0; + done = 0; + j = end; + loop { + let fresh0 = j; + j = j - 1; + if !(fresh0 > start) { + break; + } + let tmp: i32 = + *bits1.offset(j as isize) + (mid * *bits2.offset(j as isize) >> ALLOC_STEPS); + if tmp >= *thresh.offset(j as isize) || done != 0 { + done = 1; + psum += if tmp < *cap.offset(j as isize) { + tmp + } else { + *cap.offset(j as isize) + }; + } else if tmp >= alloc_floor { + psum += alloc_floor; + } + } + if psum > total { + hi = mid; + } else { + lo = mid; + } + i += 1; + } + psum = 0; + done = 0; + j = end; + loop { + let fresh1 = j; + j = j - 1; + if !(fresh1 > start) { + break; + } + let mut tmp_0: i32 = + *bits1.offset(j as isize) + (lo * *bits2.offset(j as isize) >> ALLOC_STEPS); + if tmp_0 < *thresh.offset(j as isize) && done == 0 { + if tmp_0 >= alloc_floor { + tmp_0 = alloc_floor; + } else { + tmp_0 = 0; + } + } else { + done = 1; + } + tmp_0 = if tmp_0 < *cap.offset(j as isize) { + tmp_0 + } else { + *cap.offset(j as isize) + }; + *bits.offset(j as isize) = tmp_0; + psum += tmp_0; + } + codedBands = end; + loop { + let mut band_width: i32 = 0; + let mut band_bits: i32 = 0; + let mut rem: i32 = 0; + j = codedBands - 1; + if j <= skip_start { + total += skip_rsv; + break; + } else { + left = total - psum; + percoeff = celt_udiv( + left as u32, + (*((*m).eBands).offset(codedBands as isize) as i32 + - *((*m).eBands).offset(start as isize) as i32) as u32, + ) as i32; + left -= (*((*m).eBands).offset(codedBands as isize) as i32 + - *((*m).eBands).offset(start as isize) as i32) + * percoeff; + rem = if left + - (*((*m).eBands).offset(j as isize) as i32 + - *((*m).eBands).offset(start as isize) as i32) + > 0 + { + left - (*((*m).eBands).offset(j as isize) as i32 + - *((*m).eBands).offset(start as isize) as i32) + } else { + 0 + }; + band_width = *((*m).eBands).offset(codedBands as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32; + band_bits = *bits.offset(j as isize) + percoeff * band_width + rem; + if band_bits + >= (if *thresh.offset(j as isize) > alloc_floor + ((1) << 3) { + *thresh.offset(j as isize) + } else { + alloc_floor + ((1) << 3) + }) + { + if encode != 0 { + let mut depth_threshold: i32 = 0; + if codedBands > 17 { + depth_threshold = if j < prev { 7 } else { 9 }; + } else { + depth_threshold = 0; + } + if codedBands <= start + 2 + || band_bits > depth_threshold * band_width << LM << BITRES >> 4 + && j <= signalBandwidth + { + ec_enc_bit_logp(ec, 1, 1); + break; + } else { + ec_enc_bit_logp(ec, 0, 1); + } + } else if ec_dec_bit_logp(ec, 1) != 0 { + break; + } + psum += (1) << BITRES; + band_bits -= (1) << BITRES; + } + psum -= *bits.offset(j as isize) + intensity_rsv; + if intensity_rsv > 0 { + intensity_rsv = LOG2_FRAC_TABLE[(j - start) as usize] as i32; + } + psum += intensity_rsv; + if band_bits >= alloc_floor { + psum += alloc_floor; + *bits.offset(j as isize) = alloc_floor; + } else { + *bits.offset(j as isize) = 0; + } + codedBands -= 1; + } + } + assert!(codedBands > start); + if intensity_rsv > 0 { + if encode != 0 { + *intensity = if *intensity < codedBands { + *intensity + } else { + codedBands + }; + ec_enc_uint( + ec, + (*intensity - start) as u32, + (codedBands + 1 - start) as u32, + ); + } else { + *intensity = (start as u32) + .wrapping_add(ec_dec_uint(ec, (codedBands + 1 - start) as u32)) + as i32; + } + } else { + *intensity = 0; + } + if *intensity <= start { + total += dual_stereo_rsv; + dual_stereo_rsv = 0; + } + if dual_stereo_rsv > 0 { + if encode != 0 { + ec_enc_bit_logp(ec, *dual_stereo, 1); + } else { + *dual_stereo = ec_dec_bit_logp(ec, 1); + } + } else { + *dual_stereo = 0; + } + left = total - psum; + percoeff = celt_udiv( + left as u32, + (*((*m).eBands).offset(codedBands as isize) as i32 + - *((*m).eBands).offset(start as isize) as i32) as u32, + ) as i32; + left -= (*((*m).eBands).offset(codedBands as isize) as i32 + - *((*m).eBands).offset(start as isize) as i32) + * percoeff; + j = start; + while j < codedBands { + *bits.offset(j as isize) += percoeff + * (*((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32); + j += 1; + } + j = start; + while j < codedBands { + let tmp_1: i32 = if left + < *((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32 + { + left + } else { + *((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32 + }; + *bits.offset(j as isize) += tmp_1; + left -= tmp_1; + j += 1; + } + balance = 0; + j = start; + while j < codedBands { + let mut N0: i32 = 0; + let mut N: i32 = 0; + let mut den: i32 = 0; + let mut offset: i32 = 0; + let mut NClogN: i32 = 0; + let mut excess: i32 = 0; + let mut bit: i32 = 0; + assert!(*bits.offset(j as isize) >= 0); + N0 = *((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32; + N = N0 << LM; + bit = *bits.offset(j as isize) + balance; + if N > 1 { + excess = if bit - *cap.offset(j as isize) > 0 { + bit - *cap.offset(j as isize) + } else { + 0 + }; + *bits.offset(j as isize) = bit - excess; + den = C * N + + (if C == 2 && N > 2 && *dual_stereo == 0 && j < *intensity { + 1 + } else { + 0 + }); + NClogN = den * (*((*m).logN).offset(j as isize) as i32 + logM); + offset = (NClogN >> 1) - den * FINE_OFFSET; + if N == 2 { + offset += den << BITRES >> 2; + } + if *bits.offset(j as isize) + offset < (den * 2) << BITRES { + offset += NClogN >> 2; + } else if *bits.offset(j as isize) + offset < (den * 3) << BITRES { + offset += NClogN >> 3; + } + *ebits.offset(j as isize) = if 0 > *bits.offset(j as isize) + offset + (den << 3 - 1) { + 0 + } else { + *bits.offset(j as isize) + offset + (den << 3 - 1) + }; + *ebits.offset(j as isize) = + (celt_udiv(*ebits.offset(j as isize) as u32, den as u32) >> BITRES) as i32; + if C * *ebits.offset(j as isize) > *bits.offset(j as isize) >> BITRES { + *ebits.offset(j as isize) = *bits.offset(j as isize) >> stereo >> BITRES; + } + *ebits.offset(j as isize) = if *ebits.offset(j as isize) < 8 { + *ebits.offset(j as isize) + } else { + 8 + }; + *fine_priority.offset(j as isize) = (*ebits.offset(j as isize) * (den << BITRES) + >= *bits.offset(j as isize) + offset) + as i32; + *bits.offset(j as isize) -= C * *ebits.offset(j as isize) << BITRES; + } else { + excess = if 0 > bit - (C << 3) { + 0 + } else { + bit - (C << 3) + }; + *bits.offset(j as isize) = bit - excess; + *ebits.offset(j as isize) = 0; + *fine_priority.offset(j as isize) = 1; + } + if excess > 0 { + let mut extra_fine: i32 = 0; + let mut extra_bits: i32 = 0; + extra_fine = if (excess >> stereo + 3) < 8 - *ebits.offset(j as isize) { + excess >> stereo + 3 + } else { + 8 - *ebits.offset(j as isize) + }; + *ebits.offset(j as isize) += extra_fine; + extra_bits = extra_fine * C << BITRES; + *fine_priority.offset(j as isize) = (extra_bits >= excess - balance) as i32; + excess -= extra_bits; + } + balance = excess; + assert!(*bits.offset(j as isize) >= 0); + assert!(*ebits.offset(j as isize) >= 0); + j += 1; + } + *_balance = balance; + while j < end { + *ebits.offset(j as isize) = *bits.offset(j as isize) >> stereo >> BITRES; + assert!(C * *ebits.offset(j as isize) << 3 == *bits.offset(j as isize)); + *bits.offset(j as isize) = 0; + *fine_priority.offset(j as isize) = (*ebits.offset(j as isize) < 1) as i32; + j += 1; + } + return codedBands; +} +pub unsafe fn clt_compute_allocation( + m: *const OpusCustomMode, + start: i32, + end: i32, + offsets: *const i32, + cap: *const i32, + alloc_trim: i32, + intensity: *mut i32, + dual_stereo: *mut i32, + mut total: i32, + balance: *mut i32, + pulses: *mut i32, + ebits: *mut i32, + fine_priority: *mut i32, + C: i32, + LM: i32, + ec: &mut ec_ctx, + encode: i32, + prev: i32, + signalBandwidth: i32, +) -> i32 { + let mut lo: i32 = 0; + let mut hi: i32 = 0; + let mut len: i32 = 0; + let mut j: i32 = 0; + let mut codedBands: i32 = 0; + let mut skip_start: i32 = 0; + let mut skip_rsv: i32 = 0; + let mut intensity_rsv: i32 = 0; + let mut dual_stereo_rsv: i32 = 0; + total = if total > 0 { total } else { 0 }; + len = (*m).nbEBands; + skip_start = start; + skip_rsv = if total >= (1) << BITRES { + (1) << BITRES + } else { + 0 + }; + total -= skip_rsv; + dual_stereo_rsv = 0; + intensity_rsv = dual_stereo_rsv; + if C == 2 { + intensity_rsv = LOG2_FRAC_TABLE[(end - start) as usize] as i32; + if intensity_rsv > total { + intensity_rsv = 0; + } else { + total -= intensity_rsv; + dual_stereo_rsv = if total >= (1) << BITRES { + (1) << BITRES + } else { + 0 + }; + total -= dual_stereo_rsv; + } + } + let vla = len as usize; + let mut bits1: Vec = ::std::vec::from_elem(0, vla); + let vla_0 = len as usize; + let mut bits2: Vec = ::std::vec::from_elem(0, vla_0); + let vla_1 = len as usize; + let mut thresh: Vec = ::std::vec::from_elem(0, vla_1); + let vla_2 = len as usize; + let mut trim_offset: Vec = ::std::vec::from_elem(0, vla_2); + j = start; + while j < end { + *thresh.as_mut_ptr().offset(j as isize) = if C << 3 + > 3 * (*((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32) + << LM + << 3 + >> 4 + { + C << 3 + } else { + 3 * (*((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32) + << LM + << 3 + >> 4 + }; + *trim_offset.as_mut_ptr().offset(j as isize) = C + * (*((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32) + * (alloc_trim - 5 - LM) + * (end - j - 1) + * ((1) << LM + BITRES) + >> 6; + if (*((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32) + << LM + == 1 + { + *trim_offset.as_mut_ptr().offset(j as isize) -= C << BITRES; + } + j += 1; + } + lo = 1; + hi = (*m).nbAllocVectors - 1; + loop { + let mut done: i32 = 0; + let mut psum: i32 = 0; + let mid: i32 = lo + hi >> 1; + j = end; + loop { + let fresh2 = j; + j = j - 1; + if !(fresh2 > start) { + break; + } + let mut bitsj: i32 = 0; + let N: i32 = *((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32; + bitsj = + (C * N * *((*m).allocVectors).offset((mid * len + j) as isize) as i32) << LM >> 2; + if bitsj > 0 { + bitsj = if 0 > bitsj + *trim_offset.as_mut_ptr().offset(j as isize) { + 0 + } else { + bitsj + *trim_offset.as_mut_ptr().offset(j as isize) + }; + } + bitsj += *offsets.offset(j as isize); + if bitsj >= *thresh.as_mut_ptr().offset(j as isize) || done != 0 { + done = 1; + psum += if bitsj < *cap.offset(j as isize) { + bitsj + } else { + *cap.offset(j as isize) + }; + } else if bitsj >= C << BITRES { + psum += C << BITRES; + } + } + if psum > total { + hi = mid - 1; + } else { + lo = mid + 1; + } + if !(lo <= hi) { + break; + } + } + let fresh3 = lo; + lo = lo - 1; + hi = fresh3; + j = start; + while j < end { + let mut bits1j: i32 = 0; + let mut bits2j: i32 = 0; + let N_0: i32 = *((*m).eBands).offset((j + 1) as isize) as i32 + - *((*m).eBands).offset(j as isize) as i32; + bits1j = (C * N_0 * *((*m).allocVectors).offset((lo * len + j) as isize) as i32) << LM >> 2; + bits2j = if hi >= (*m).nbAllocVectors { + *cap.offset(j as isize) + } else { + (C * N_0 * *((*m).allocVectors).offset((hi * len + j) as isize) as i32) << LM >> 2 + }; + if bits1j > 0 { + bits1j = if 0 > bits1j + *trim_offset.as_mut_ptr().offset(j as isize) { + 0 + } else { + bits1j + *trim_offset.as_mut_ptr().offset(j as isize) + }; + } + if bits2j > 0 { + bits2j = if 0 > bits2j + *trim_offset.as_mut_ptr().offset(j as isize) { + 0 + } else { + bits2j + *trim_offset.as_mut_ptr().offset(j as isize) + }; + } + if lo > 0 { + bits1j += *offsets.offset(j as isize); + } + bits2j += *offsets.offset(j as isize); + if *offsets.offset(j as isize) > 0 { + skip_start = j; + } + bits2j = if 0 > bits2j - bits1j { + 0 + } else { + bits2j - bits1j + }; + *bits1.as_mut_ptr().offset(j as isize) = bits1j; + *bits2.as_mut_ptr().offset(j as isize) = bits2j; + j += 1; + } + codedBands = interp_bits2pulses( + m, + start, + end, + skip_start, + bits1.as_mut_ptr(), + bits2.as_mut_ptr(), + thresh.as_mut_ptr(), + cap, + total, + balance, + skip_rsv, + intensity, + intensity_rsv, + dual_stereo, + dual_stereo_rsv, + pulses, + ebits, + fine_priority, + C, + LM, + ec, + encode, + prev, + signalBandwidth, + ); + return codedBands; +} diff --git a/vendor/unsafe-libopus/src/celt/snapshots/unsafe_libopus__celt__cwrs__test__pvq_u_table.snap b/vendor/unsafe-libopus/src/celt/snapshots/unsafe_libopus__celt__cwrs__test__pvq_u_table.snap new file mode 100644 index 00000000..9eb1add7 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/snapshots/unsafe_libopus__celt__cwrs__test__pvq_u_table.snap @@ -0,0 +1,1382 @@ +--- +source: src/celt/cwrs.rs +expression: table +--- +(0, 0) = 1, +(0, 1) = 0, +(0, 2) = 0, +(0, 3) = 0, +(0, 4) = 0, +(0, 5) = 0, +(0, 6) = 0, +(0, 7) = 0, +(0, 8) = 0, +(0, 9) = 0, +(0, 10) = 0, +(0, 11) = 0, +(0, 12) = 0, +(0, 13) = 0, +(0, 14) = 0, +(0, 15) = 0, +(0, 16) = 0, +(0, 17) = 0, +(0, 18) = 0, +(0, 19) = 0, +(0, 20) = 0, +(0, 21) = 0, +(0, 22) = 0, +(0, 23) = 0, +(0, 24) = 0, +(0, 25) = 0, +(0, 26) = 0, +(0, 27) = 0, +(0, 28) = 0, +(0, 29) = 0, +(0, 30) = 0, +(0, 31) = 0, +(0, 32) = 0, +(0, 33) = 0, +(0, 34) = 0, +(0, 35) = 0, +(0, 36) = 0, +(0, 37) = 0, +(0, 38) = 0, +(0, 39) = 0, +(0, 40) = 0, +(0, 41) = 0, +(0, 42) = 0, +(0, 43) = 0, +(0, 44) = 0, +(0, 45) = 0, +(0, 46) = 0, +(0, 47) = 0, +(0, 48) = 0, +(0, 49) = 0, +(0, 50) = 0, +(0, 51) = 0, +(0, 52) = 0, +(0, 53) = 0, +(0, 54) = 0, +(0, 55) = 0, +(0, 56) = 0, +(0, 57) = 0, +(0, 58) = 0, +(0, 59) = 0, +(0, 60) = 0, +(0, 61) = 0, +(0, 62) = 0, +(0, 63) = 0, +(0, 64) = 0, +(0, 65) = 0, +(0, 66) = 0, +(0, 67) = 0, +(0, 68) = 0, +(0, 69) = 0, +(0, 70) = 0, +(0, 71) = 0, +(0, 72) = 0, +(0, 73) = 0, +(0, 74) = 0, +(0, 75) = 0, +(0, 76) = 0, +(0, 77) = 0, +(0, 78) = 0, +(0, 79) = 0, +(0, 80) = 0, +(0, 81) = 0, +(0, 82) = 0, +(0, 83) = 0, +(0, 84) = 0, +(0, 85) = 0, +(0, 86) = 0, +(0, 87) = 0, +(0, 88) = 0, +(0, 89) = 0, +(0, 90) = 0, +(0, 91) = 0, +(0, 92) = 0, +(0, 93) = 0, +(0, 94) = 0, +(0, 95) = 0, +(0, 96) = 0, +(0, 97) = 0, +(0, 98) = 0, +(0, 99) = 0, +(0, 100) = 0, +(0, 101) = 0, +(0, 102) = 0, +(0, 103) = 0, +(0, 104) = 0, +(0, 105) = 0, +(0, 106) = 0, +(0, 107) = 0, +(0, 108) = 0, +(0, 109) = 0, +(0, 110) = 0, +(0, 111) = 0, +(0, 112) = 0, +(0, 113) = 0, +(0, 114) = 0, +(0, 115) = 0, +(0, 116) = 0, +(0, 117) = 0, +(0, 118) = 0, +(0, 119) = 0, +(0, 120) = 0, +(0, 121) = 0, +(0, 122) = 0, +(0, 123) = 0, +(0, 124) = 0, +(0, 125) = 0, +(0, 126) = 0, +(0, 127) = 0, +(0, 128) = 0, +(0, 129) = 0, +(0, 130) = 0, +(0, 131) = 0, +(0, 132) = 0, +(0, 133) = 0, +(0, 134) = 0, +(0, 135) = 0, +(0, 136) = 0, +(0, 137) = 0, +(0, 138) = 0, +(0, 139) = 0, +(0, 140) = 0, +(0, 141) = 0, +(0, 142) = 0, +(0, 143) = 0, +(0, 144) = 0, +(0, 145) = 0, +(0, 146) = 0, +(0, 147) = 0, +(0, 148) = 0, +(0, 149) = 0, +(0, 150) = 0, +(0, 151) = 0, +(0, 152) = 0, +(0, 153) = 0, +(0, 154) = 0, +(0, 155) = 0, +(0, 156) = 0, +(0, 157) = 0, +(0, 158) = 0, +(0, 159) = 0, +(0, 160) = 0, +(0, 161) = 0, +(0, 162) = 0, +(0, 163) = 0, +(0, 164) = 0, +(0, 165) = 0, +(0, 166) = 0, +(0, 167) = 0, +(0, 168) = 0, +(0, 169) = 0, +(0, 170) = 0, +(0, 171) = 0, +(0, 172) = 0, +(0, 173) = 0, +(0, 174) = 0, +(0, 175) = 0, +(0, 176) = 0, +(1, 0) = 0, +(1, 1) = 1, +(1, 2) = 1, +(1, 3) = 1, +(1, 4) = 1, +(1, 5) = 1, +(1, 6) = 1, +(1, 7) = 1, +(1, 8) = 1, +(1, 9) = 1, +(1, 10) = 1, +(1, 11) = 1, +(1, 12) = 1, +(1, 13) = 1, +(1, 14) = 1, +(1, 15) = 1, +(1, 16) = 1, +(1, 17) = 1, +(1, 18) = 1, +(1, 19) = 1, +(1, 20) = 1, +(1, 21) = 1, +(1, 22) = 1, +(1, 23) = 1, +(1, 24) = 1, +(1, 25) = 1, +(1, 26) = 1, +(1, 27) = 1, +(1, 28) = 1, +(1, 29) = 1, +(1, 30) = 1, +(1, 31) = 1, +(1, 32) = 1, +(1, 33) = 1, +(1, 34) = 1, +(1, 35) = 1, +(1, 36) = 1, +(1, 37) = 1, +(1, 38) = 1, +(1, 39) = 1, +(1, 40) = 1, +(1, 41) = 1, +(1, 42) = 1, +(1, 43) = 1, +(1, 44) = 1, +(1, 45) = 1, +(1, 46) = 1, +(1, 47) = 1, +(1, 48) = 1, +(1, 49) = 1, +(1, 50) = 1, +(1, 51) = 1, +(1, 52) = 1, +(1, 53) = 1, +(1, 54) = 1, +(1, 55) = 1, +(1, 56) = 1, +(1, 57) = 1, +(1, 58) = 1, +(1, 59) = 1, +(1, 60) = 1, +(1, 61) = 1, +(1, 62) = 1, +(1, 63) = 1, +(1, 64) = 1, +(1, 65) = 1, +(1, 66) = 1, +(1, 67) = 1, +(1, 68) = 1, +(1, 69) = 1, +(1, 70) = 1, +(1, 71) = 1, +(1, 72) = 1, +(1, 73) = 1, +(1, 74) = 1, +(1, 75) = 1, +(1, 76) = 1, +(1, 77) = 1, +(1, 78) = 1, +(1, 79) = 1, +(1, 80) = 1, +(1, 81) = 1, +(1, 82) = 1, +(1, 83) = 1, +(1, 84) = 1, +(1, 85) = 1, +(1, 86) = 1, +(1, 87) = 1, +(1, 88) = 1, +(1, 89) = 1, +(1, 90) = 1, +(1, 91) = 1, +(1, 92) = 1, +(1, 93) = 1, +(1, 94) = 1, +(1, 95) = 1, +(1, 96) = 1, +(1, 97) = 1, +(1, 98) = 1, +(1, 99) = 1, +(1, 100) = 1, +(1, 101) = 1, +(1, 102) = 1, +(1, 103) = 1, +(1, 104) = 1, +(1, 105) = 1, +(1, 106) = 1, +(1, 107) = 1, +(1, 108) = 1, +(1, 109) = 1, +(1, 110) = 1, +(1, 111) = 1, +(1, 112) = 1, +(1, 113) = 1, +(1, 114) = 1, +(1, 115) = 1, +(1, 116) = 1, +(1, 117) = 1, +(1, 118) = 1, +(1, 119) = 1, +(1, 120) = 1, +(1, 121) = 1, +(1, 122) = 1, +(1, 123) = 1, +(1, 124) = 1, +(1, 125) = 1, +(1, 126) = 1, +(1, 127) = 1, +(1, 128) = 1, +(1, 129) = 1, +(1, 130) = 1, +(1, 131) = 1, +(1, 132) = 1, +(1, 133) = 1, +(1, 134) = 1, +(1, 135) = 1, +(1, 136) = 1, +(1, 137) = 1, +(1, 138) = 1, +(1, 139) = 1, +(1, 140) = 1, +(1, 141) = 1, +(1, 142) = 1, +(1, 143) = 1, +(1, 144) = 1, +(1, 145) = 1, +(1, 146) = 1, +(1, 147) = 1, +(1, 148) = 1, +(1, 149) = 1, +(1, 150) = 1, +(1, 151) = 1, +(1, 152) = 1, +(1, 153) = 1, +(1, 154) = 1, +(1, 155) = 1, +(1, 156) = 1, +(1, 157) = 1, +(1, 158) = 1, +(1, 159) = 1, +(1, 160) = 1, +(1, 161) = 1, +(1, 162) = 1, +(1, 163) = 1, +(1, 164) = 1, +(1, 165) = 1, +(1, 166) = 1, +(1, 167) = 1, +(1, 168) = 1, +(1, 169) = 1, +(1, 170) = 1, +(1, 171) = 1, +(1, 172) = 1, +(1, 173) = 1, +(1, 174) = 1, +(1, 175) = 1, +(1, 176) = 1, +(2, 0) = 0, +(2, 1) = 1, +(2, 2) = 3, +(2, 3) = 5, +(2, 4) = 7, +(2, 5) = 9, +(2, 6) = 11, +(2, 7) = 13, +(2, 8) = 15, +(2, 9) = 17, +(2, 10) = 19, +(2, 11) = 21, +(2, 12) = 23, +(2, 13) = 25, +(2, 14) = 27, +(2, 15) = 29, +(2, 16) = 31, +(2, 17) = 33, +(2, 18) = 35, +(2, 19) = 37, +(2, 20) = 39, +(2, 21) = 41, +(2, 22) = 43, +(2, 23) = 45, +(2, 24) = 47, +(2, 25) = 49, +(2, 26) = 51, +(2, 27) = 53, +(2, 28) = 55, +(2, 29) = 57, +(2, 30) = 59, +(2, 31) = 61, +(2, 32) = 63, +(2, 33) = 65, +(2, 34) = 67, +(2, 35) = 69, +(2, 36) = 71, +(2, 37) = 73, +(2, 38) = 75, +(2, 39) = 77, +(2, 40) = 79, +(2, 41) = 81, +(2, 42) = 83, +(2, 43) = 85, +(2, 44) = 87, +(2, 45) = 89, +(2, 46) = 91, +(2, 47) = 93, +(2, 48) = 95, +(2, 49) = 97, +(2, 50) = 99, +(2, 51) = 101, +(2, 52) = 103, +(2, 53) = 105, +(2, 54) = 107, +(2, 55) = 109, +(2, 56) = 111, +(2, 57) = 113, +(2, 58) = 115, +(2, 59) = 117, +(2, 60) = 119, +(2, 61) = 121, +(2, 62) = 123, +(2, 63) = 125, +(2, 64) = 127, +(2, 65) = 129, +(2, 66) = 131, +(2, 67) = 133, +(2, 68) = 135, +(2, 69) = 137, +(2, 70) = 139, +(2, 71) = 141, +(2, 72) = 143, +(2, 73) = 145, +(2, 74) = 147, +(2, 75) = 149, +(2, 76) = 151, +(2, 77) = 153, +(2, 78) = 155, +(2, 79) = 157, +(2, 80) = 159, +(2, 81) = 161, +(2, 82) = 163, +(2, 83) = 165, +(2, 84) = 167, +(2, 85) = 169, +(2, 86) = 171, +(2, 87) = 173, +(2, 88) = 175, +(2, 89) = 177, +(2, 90) = 179, +(2, 91) = 181, +(2, 92) = 183, +(2, 93) = 185, +(2, 94) = 187, +(2, 95) = 189, +(2, 96) = 191, +(2, 97) = 193, +(2, 98) = 195, +(2, 99) = 197, +(2, 100) = 199, +(2, 101) = 201, +(2, 102) = 203, +(2, 103) = 205, +(2, 104) = 207, +(2, 105) = 209, +(2, 106) = 211, +(2, 107) = 213, +(2, 108) = 215, +(2, 109) = 217, +(2, 110) = 219, +(2, 111) = 221, +(2, 112) = 223, +(2, 113) = 225, +(2, 114) = 227, +(2, 115) = 229, +(2, 116) = 231, +(2, 117) = 233, +(2, 118) = 235, +(2, 119) = 237, +(2, 120) = 239, +(2, 121) = 241, +(2, 122) = 243, +(2, 123) = 245, +(2, 124) = 247, +(2, 125) = 249, +(2, 126) = 251, +(2, 127) = 253, +(2, 128) = 255, +(2, 129) = 257, +(2, 130) = 259, +(2, 131) = 261, +(2, 132) = 263, +(2, 133) = 265, +(2, 134) = 267, +(2, 135) = 269, +(2, 136) = 271, +(2, 137) = 273, +(2, 138) = 275, +(2, 139) = 277, +(2, 140) = 279, +(2, 141) = 281, +(2, 142) = 283, +(2, 143) = 285, +(2, 144) = 287, +(2, 145) = 289, +(2, 146) = 291, +(2, 147) = 293, +(2, 148) = 295, +(2, 149) = 297, +(2, 150) = 299, +(2, 151) = 301, +(2, 152) = 303, +(2, 153) = 305, +(2, 154) = 307, +(2, 155) = 309, +(2, 156) = 311, +(2, 157) = 313, +(2, 158) = 315, +(2, 159) = 317, +(2, 160) = 319, +(2, 161) = 321, +(2, 162) = 323, +(2, 163) = 325, +(2, 164) = 327, +(2, 165) = 329, +(2, 166) = 331, +(2, 167) = 333, +(2, 168) = 335, +(2, 169) = 337, +(2, 170) = 339, +(2, 171) = 341, +(2, 172) = 343, +(2, 173) = 345, +(2, 174) = 347, +(2, 175) = 349, +(2, 176) = 351, +(3, 0) = 0, +(3, 1) = 1, +(3, 2) = 5, +(3, 3) = 13, +(3, 4) = 25, +(3, 5) = 41, +(3, 6) = 61, +(3, 7) = 85, +(3, 8) = 113, +(3, 9) = 145, +(3, 10) = 181, +(3, 11) = 221, +(3, 12) = 265, +(3, 13) = 313, +(3, 14) = 365, +(3, 15) = 421, +(3, 16) = 481, +(3, 17) = 545, +(3, 18) = 613, +(3, 19) = 685, +(3, 20) = 761, +(3, 21) = 841, +(3, 22) = 925, +(3, 23) = 1013, +(3, 24) = 1105, +(3, 25) = 1201, +(3, 26) = 1301, +(3, 27) = 1405, +(3, 28) = 1513, +(3, 29) = 1625, +(3, 30) = 1741, +(3, 31) = 1861, +(3, 32) = 1985, +(3, 33) = 2113, +(3, 34) = 2245, +(3, 35) = 2381, +(3, 36) = 2521, +(3, 37) = 2665, +(3, 38) = 2813, +(3, 39) = 2965, +(3, 40) = 3121, +(3, 41) = 3281, +(3, 42) = 3445, +(3, 43) = 3613, +(3, 44) = 3785, +(3, 45) = 3961, +(3, 46) = 4141, +(3, 47) = 4325, +(3, 48) = 4513, +(3, 49) = 4705, +(3, 50) = 4901, +(3, 51) = 5101, +(3, 52) = 5305, +(3, 53) = 5513, +(3, 54) = 5725, +(3, 55) = 5941, +(3, 56) = 6161, +(3, 57) = 6385, +(3, 58) = 6613, +(3, 59) = 6845, +(3, 60) = 7081, +(3, 61) = 7321, +(3, 62) = 7565, +(3, 63) = 7813, +(3, 64) = 8065, +(3, 65) = 8321, +(3, 66) = 8581, +(3, 67) = 8845, +(3, 68) = 9113, +(3, 69) = 9385, +(3, 70) = 9661, +(3, 71) = 9941, +(3, 72) = 10225, +(3, 73) = 10513, +(3, 74) = 10805, +(3, 75) = 11101, +(3, 76) = 11401, +(3, 77) = 11705, +(3, 78) = 12013, +(3, 79) = 12325, +(3, 80) = 12641, +(3, 81) = 12961, +(3, 82) = 13285, +(3, 83) = 13613, +(3, 84) = 13945, +(3, 85) = 14281, +(3, 86) = 14621, +(3, 87) = 14965, +(3, 88) = 15313, +(3, 89) = 15665, +(3, 90) = 16021, +(3, 91) = 16381, +(3, 92) = 16745, +(3, 93) = 17113, +(3, 94) = 17485, +(3, 95) = 17861, +(3, 96) = 18241, +(3, 97) = 18625, +(3, 98) = 19013, +(3, 99) = 19405, +(3, 100) = 19801, +(3, 101) = 20201, +(3, 102) = 20605, +(3, 103) = 21013, +(3, 104) = 21425, +(3, 105) = 21841, +(3, 106) = 22261, +(3, 107) = 22685, +(3, 108) = 23113, +(3, 109) = 23545, +(3, 110) = 23981, +(3, 111) = 24421, +(3, 112) = 24865, +(3, 113) = 25313, +(3, 114) = 25765, +(3, 115) = 26221, +(3, 116) = 26681, +(3, 117) = 27145, +(3, 118) = 27613, +(3, 119) = 28085, +(3, 120) = 28561, +(3, 121) = 29041, +(3, 122) = 29525, +(3, 123) = 30013, +(3, 124) = 30505, +(3, 125) = 31001, +(3, 126) = 31501, +(3, 127) = 32005, +(3, 128) = 32513, +(3, 129) = 33025, +(3, 130) = 33541, +(3, 131) = 34061, +(3, 132) = 34585, +(3, 133) = 35113, +(3, 134) = 35645, +(3, 135) = 36181, +(3, 136) = 36721, +(3, 137) = 37265, +(3, 138) = 37813, +(3, 139) = 38365, +(3, 140) = 38921, +(3, 141) = 39481, +(3, 142) = 40045, +(3, 143) = 40613, +(3, 144) = 41185, +(3, 145) = 41761, +(3, 146) = 42341, +(3, 147) = 42925, +(3, 148) = 43513, +(3, 149) = 44105, +(3, 150) = 44701, +(3, 151) = 45301, +(3, 152) = 45905, +(3, 153) = 46513, +(3, 154) = 47125, +(3, 155) = 47741, +(3, 156) = 48361, +(3, 157) = 48985, +(3, 158) = 49613, +(3, 159) = 50245, +(3, 160) = 50881, +(3, 161) = 51521, +(3, 162) = 52165, +(3, 163) = 52813, +(3, 164) = 53465, +(3, 165) = 54121, +(3, 166) = 54781, +(3, 167) = 55445, +(3, 168) = 56113, +(3, 169) = 56785, +(3, 170) = 57461, +(3, 171) = 58141, +(3, 172) = 58825, +(3, 173) = 59513, +(3, 174) = 60205, +(3, 175) = 60901, +(3, 176) = 61601, +(4, 0) = 0, +(4, 1) = 1, +(4, 2) = 7, +(4, 3) = 25, +(4, 4) = 63, +(4, 5) = 129, +(4, 6) = 231, +(4, 7) = 377, +(4, 8) = 575, +(4, 9) = 833, +(4, 10) = 1159, +(4, 11) = 1561, +(4, 12) = 2047, +(4, 13) = 2625, +(4, 14) = 3303, +(4, 15) = 4089, +(4, 16) = 4991, +(4, 17) = 6017, +(4, 18) = 7175, +(4, 19) = 8473, +(4, 20) = 9919, +(4, 21) = 11521, +(4, 22) = 13287, +(4, 23) = 15225, +(4, 24) = 17343, +(4, 25) = 19649, +(4, 26) = 22151, +(4, 27) = 24857, +(4, 28) = 27775, +(4, 29) = 30913, +(4, 30) = 34279, +(4, 31) = 37881, +(4, 32) = 41727, +(4, 33) = 45825, +(4, 34) = 50183, +(4, 35) = 54809, +(4, 36) = 59711, +(4, 37) = 64897, +(4, 38) = 70375, +(4, 39) = 76153, +(4, 40) = 82239, +(4, 41) = 88641, +(4, 42) = 95367, +(4, 43) = 102425, +(4, 44) = 109823, +(4, 45) = 117569, +(4, 46) = 125671, +(4, 47) = 134137, +(4, 48) = 142975, +(4, 49) = 152193, +(4, 50) = 161799, +(4, 51) = 171801, +(4, 52) = 182207, +(4, 53) = 193025, +(4, 54) = 204263, +(4, 55) = 215929, +(4, 56) = 228031, +(4, 57) = 240577, +(4, 58) = 253575, +(4, 59) = 267033, +(4, 60) = 280959, +(4, 61) = 295361, +(4, 62) = 310247, +(4, 63) = 325625, +(4, 64) = 341503, +(4, 65) = 357889, +(4, 66) = 374791, +(4, 67) = 392217, +(4, 68) = 410175, +(4, 69) = 428673, +(4, 70) = 447719, +(4, 71) = 467321, +(4, 72) = 487487, +(4, 73) = 508225, +(4, 74) = 529543, +(4, 75) = 551449, +(4, 76) = 573951, +(4, 77) = 597057, +(4, 78) = 620775, +(4, 79) = 645113, +(4, 80) = 670079, +(4, 81) = 695681, +(4, 82) = 721927, +(4, 83) = 748825, +(4, 84) = 776383, +(4, 85) = 804609, +(4, 86) = 833511, +(4, 87) = 863097, +(4, 88) = 893375, +(4, 89) = 924353, +(4, 90) = 956039, +(4, 91) = 988441, +(4, 92) = 1021567, +(4, 93) = 1055425, +(4, 94) = 1090023, +(4, 95) = 1125369, +(4, 96) = 1161471, +(4, 97) = 1198337, +(4, 98) = 1235975, +(4, 99) = 1274393, +(4, 100) = 1313599, +(4, 101) = 1353601, +(4, 102) = 1394407, +(4, 103) = 1436025, +(4, 104) = 1478463, +(4, 105) = 1521729, +(4, 106) = 1565831, +(4, 107) = 1610777, +(4, 108) = 1656575, +(4, 109) = 1703233, +(4, 110) = 1750759, +(4, 111) = 1799161, +(4, 112) = 1848447, +(4, 113) = 1898625, +(4, 114) = 1949703, +(4, 115) = 2001689, +(4, 116) = 2054591, +(4, 117) = 2108417, +(4, 118) = 2163175, +(4, 119) = 2218873, +(4, 120) = 2275519, +(4, 121) = 2333121, +(4, 122) = 2391687, +(4, 123) = 2451225, +(4, 124) = 2511743, +(4, 125) = 2573249, +(4, 126) = 2635751, +(4, 127) = 2699257, +(4, 128) = 2763775, +(4, 129) = 2829313, +(4, 130) = 2895879, +(4, 131) = 2963481, +(4, 132) = 3032127, +(4, 133) = 3101825, +(4, 134) = 3172583, +(4, 135) = 3244409, +(4, 136) = 3317311, +(4, 137) = 3391297, +(4, 138) = 3466375, +(4, 139) = 3542553, +(4, 140) = 3619839, +(4, 141) = 3698241, +(4, 142) = 3777767, +(4, 143) = 3858425, +(4, 144) = 3940223, +(4, 145) = 4023169, +(4, 146) = 4107271, +(4, 147) = 4192537, +(4, 148) = 4278975, +(4, 149) = 4366593, +(4, 150) = 4455399, +(4, 151) = 4545401, +(4, 152) = 4636607, +(4, 153) = 4729025, +(4, 154) = 4822663, +(4, 155) = 4917529, +(4, 156) = 5013631, +(4, 157) = 5110977, +(4, 158) = 5209575, +(4, 159) = 5309433, +(4, 160) = 5410559, +(4, 161) = 5512961, +(4, 162) = 5616647, +(4, 163) = 5721625, +(4, 164) = 5827903, +(4, 165) = 5935489, +(4, 166) = 6044391, +(4, 167) = 6154617, +(4, 168) = 6266175, +(4, 169) = 6379073, +(4, 170) = 6493319, +(4, 171) = 6608921, +(4, 172) = 6725887, +(4, 173) = 6844225, +(4, 174) = 6963943, +(4, 175) = 7085049, +(4, 176) = 7207551, +(5, 0) = 0, +(5, 1) = 1, +(5, 2) = 9, +(5, 3) = 41, +(5, 4) = 129, +(5, 5) = 321, +(5, 6) = 681, +(5, 7) = 1289, +(5, 8) = 2241, +(5, 9) = 3649, +(5, 10) = 5641, +(5, 11) = 8361, +(5, 12) = 11969, +(5, 13) = 16641, +(5, 14) = 22569, +(5, 15) = 29961, +(5, 16) = 39041, +(5, 17) = 50049, +(5, 18) = 63241, +(5, 19) = 78889, +(5, 20) = 97281, +(5, 21) = 118721, +(5, 22) = 143529, +(5, 23) = 172041, +(5, 24) = 204609, +(5, 25) = 241601, +(5, 26) = 283401, +(5, 27) = 330409, +(5, 28) = 383041, +(5, 29) = 441729, +(5, 30) = 506921, +(5, 31) = 579081, +(5, 32) = 658689, +(5, 33) = 746241, +(5, 34) = 842249, +(5, 35) = 947241, +(5, 36) = 1061761, +(5, 37) = 1186369, +(5, 38) = 1321641, +(5, 39) = 1468169, +(5, 40) = 1626561, +(5, 41) = 1797441, +(5, 42) = 1981449, +(5, 43) = 2179241, +(5, 44) = 2391489, +(5, 45) = 2618881, +(5, 46) = 2862121, +(5, 47) = 3121929, +(5, 48) = 3399041, +(5, 49) = 3694209, +(5, 50) = 4008201, +(5, 51) = 4341801, +(5, 52) = 4695809, +(5, 53) = 5071041, +(5, 54) = 5468329, +(5, 55) = 5888521, +(5, 56) = 6332481, +(5, 57) = 6801089, +(5, 58) = 7295241, +(5, 59) = 7815849, +(5, 60) = 8363841, +(5, 61) = 8940161, +(5, 62) = 9545769, +(5, 63) = 10181641, +(5, 64) = 10848769, +(5, 65) = 11548161, +(5, 66) = 12280841, +(5, 67) = 13047849, +(5, 68) = 13850241, +(5, 69) = 14689089, +(5, 70) = 15565481, +(5, 71) = 16480521, +(5, 72) = 17435329, +(5, 73) = 18431041, +(5, 74) = 19468809, +(5, 75) = 20549801, +(5, 76) = 21675201, +(5, 77) = 22846209, +(5, 78) = 24064041, +(5, 79) = 25329929, +(5, 80) = 26645121, +(5, 81) = 28010881, +(5, 82) = 29428489, +(5, 83) = 30899241, +(5, 84) = 32424449, +(5, 85) = 34005441, +(5, 86) = 35643561, +(5, 87) = 37340169, +(5, 88) = 39096641, +(5, 89) = 40914369, +(5, 90) = 42794761, +(5, 91) = 44739241, +(5, 92) = 46749249, +(5, 93) = 48826241, +(5, 94) = 50971689, +(5, 95) = 53187081, +(5, 96) = 55473921, +(5, 97) = 57833729, +(5, 98) = 60268041, +(5, 99) = 62778409, +(5, 100) = 65366401, +(5, 101) = 68033601, +(5, 102) = 70781609, +(5, 103) = 73612041, +(5, 104) = 76526529, +(5, 105) = 79526721, +(5, 106) = 82614281, +(5, 107) = 85790889, +(5, 108) = 89058241, +(5, 109) = 92418049, +(5, 110) = 95872041, +(5, 111) = 99421961, +(5, 112) = 103069569, +(5, 113) = 106816641, +(5, 114) = 110664969, +(5, 115) = 114616361, +(5, 116) = 118672641, +(5, 117) = 122835649, +(5, 118) = 127107241, +(5, 119) = 131489289, +(5, 120) = 135983681, +(5, 121) = 140592321, +(5, 122) = 145317129, +(5, 123) = 150160041, +(5, 124) = 155123009, +(5, 125) = 160208001, +(5, 126) = 165417001, +(5, 127) = 170752009, +(5, 128) = 176215041, +(5, 129) = 181808129, +(5, 130) = 187533321, +(5, 131) = 193392681, +(5, 132) = 199388289, +(5, 133) = 205522241, +(5, 134) = 211796649, +(5, 135) = 218213641, +(5, 136) = 224775361, +(5, 137) = 231483969, +(5, 138) = 238341641, +(5, 139) = 245350569, +(5, 140) = 252512961, +(5, 141) = 259831041, +(5, 142) = 267307049, +(5, 143) = 274943241, +(5, 144) = 282741889, +(5, 145) = 290705281, +(5, 146) = 298835721, +(5, 147) = 307135529, +(5, 148) = 315607041, +(5, 149) = 324252609, +(5, 150) = 333074601, +(5, 151) = 342075401, +(5, 152) = 351257409, +(5, 153) = 360623041, +(5, 154) = 370174729, +(5, 155) = 379914921, +(5, 156) = 389846081, +(5, 157) = 399970689, +(5, 158) = 410291241, +(5, 159) = 420810249, +(5, 160) = 431530241, +(5, 161) = 442453761, +(5, 162) = 453583369, +(5, 163) = 464921641, +(5, 164) = 476471169, +(5, 165) = 488234561, +(5, 166) = 500214441, +(5, 167) = 512413449, +(5, 168) = 524834241, +(5, 169) = 537479489, +(5, 170) = 550351881, +(5, 171) = 563454121, +(5, 172) = 576788929, +(5, 173) = 590359041, +(5, 174) = 604167209, +(5, 175) = 618216201, +(5, 176) = 632508801, +(6, 0) = 0, +(6, 1) = 1, +(6, 2) = 11, +(6, 3) = 61, +(6, 4) = 231, +(6, 5) = 681, +(6, 6) = 1683, +(6, 7) = 3653, +(6, 8) = 7183, +(6, 9) = 13073, +(6, 10) = 22363, +(6, 11) = 36365, +(6, 12) = 56695, +(6, 13) = 85305, +(6, 14) = 124515, +(6, 15) = 177045, +(6, 16) = 246047, +(6, 17) = 335137, +(6, 18) = 448427, +(6, 19) = 590557, +(6, 20) = 766727, +(6, 21) = 982729, +(6, 22) = 1244979, +(6, 23) = 1560549, +(6, 24) = 1937199, +(6, 25) = 2383409, +(6, 26) = 2908411, +(6, 27) = 3522221, +(6, 28) = 4235671, +(6, 29) = 5060441, +(6, 30) = 6009091, +(6, 31) = 7095093, +(6, 32) = 8332863, +(6, 33) = 9737793, +(6, 34) = 11326283, +(6, 35) = 13115773, +(6, 36) = 15124775, +(6, 37) = 17372905, +(6, 38) = 19880915, +(6, 39) = 22670725, +(6, 40) = 25765455, +(6, 41) = 29189457, +(6, 42) = 32968347, +(6, 43) = 37129037, +(6, 44) = 41699767, +(6, 45) = 46710137, +(6, 46) = 52191139, +(6, 47) = 58175189, +(6, 48) = 64696159, +(6, 49) = 71789409, +(6, 50) = 79491819, +(6, 51) = 87841821, +(6, 52) = 96879431, +(6, 53) = 106646281, +(6, 54) = 117185651, +(6, 55) = 128542501, +(6, 56) = 140763503, +(6, 57) = 153897073, +(6, 58) = 167993403, +(6, 59) = 183104493, +(6, 60) = 199284183, +(6, 61) = 216588185, +(6, 62) = 235074115, +(6, 63) = 254801525, +(6, 64) = 275831935, +(6, 65) = 298228865, +(6, 66) = 322057867, +(6, 67) = 347386557, +(6, 68) = 374284647, +(6, 69) = 402823977, +(6, 70) = 433078547, +(6, 71) = 465124549, +(6, 72) = 499040399, +(6, 73) = 534906769, +(6, 74) = 572806619, +(6, 75) = 612825229, +(6, 76) = 655050231, +(6, 77) = 699571641, +(6, 78) = 746481891, +(6, 79) = 795875861, +(6, 80) = 847850911, +(6, 81) = 902506913, +(6, 82) = 959946283, +(6, 83) = 1020274013, +(6, 84) = 1083597703, +(6, 85) = 1150027593, +(6, 86) = 1219676595, +(6, 87) = 1292660325, +(6, 88) = 1369097135, +(6, 89) = 1449108145, +(6, 90) = 1532817275, +(6, 91) = 1620351277, +(6, 92) = 1711839767, +(6, 93) = 1807415257, +(6, 94) = 1907213187, +(6, 95) = 2011371957, +(6, 96) = 2120032959, +(7, 0) = 0, +(7, 1) = 1, +(7, 2) = 13, +(7, 3) = 85, +(7, 4) = 377, +(7, 5) = 1289, +(7, 6) = 3653, +(7, 7) = 8989, +(7, 8) = 19825, +(7, 9) = 40081, +(7, 10) = 75517, +(7, 11) = 134245, +(7, 12) = 227305, +(7, 13) = 369305, +(7, 14) = 579125, +(7, 15) = 880685, +(7, 16) = 1303777, +(7, 17) = 1884961, +(7, 18) = 2668525, +(7, 19) = 3707509, +(7, 20) = 5064793, +(7, 21) = 6814249, +(7, 22) = 9041957, +(7, 23) = 11847485, +(7, 24) = 15345233, +(7, 25) = 19665841, +(7, 26) = 24957661, +(7, 27) = 31388293, +(7, 28) = 39146185, +(7, 29) = 48442297, +(7, 30) = 59511829, +(7, 31) = 72616013, +(7, 32) = 88043969, +(7, 33) = 106114625, +(7, 34) = 127178701, +(7, 35) = 151620757, +(7, 36) = 179861305, +(7, 37) = 212358985, +(7, 38) = 249612805, +(7, 39) = 292164445, +(7, 40) = 340600625, +(7, 41) = 395555537, +(7, 42) = 457713341, +(7, 43) = 527810725, +(7, 44) = 606639529, +(7, 45) = 695049433, +(7, 46) = 793950709, +(7, 47) = 904317037, +(7, 48) = 1027188385, +(7, 49) = 1163673953, +(7, 50) = 1314955181, +(7, 51) = 1482288821, +(7, 52) = 1667010073, +(7, 53) = 1870535785, +(7, 54) = 2094367717, +(8, 0) = 0, +(8, 1) = 1, +(8, 2) = 15, +(8, 3) = 113, +(8, 4) = 575, +(8, 5) = 2241, +(8, 6) = 7183, +(8, 7) = 19825, +(8, 8) = 48639, +(8, 9) = 108545, +(8, 10) = 224143, +(8, 11) = 433905, +(8, 12) = 795455, +(8, 13) = 1392065, +(8, 14) = 2340495, +(8, 15) = 3800305, +(8, 16) = 5984767, +(8, 17) = 9173505, +(8, 18) = 13726991, +(8, 19) = 20103025, +(8, 20) = 28875327, +(8, 21) = 40754369, +(8, 22) = 56610575, +(8, 23) = 77500017, +(8, 24) = 104692735, +(8, 25) = 139703809, +(8, 26) = 184327311, +(8, 27) = 240673265, +(8, 28) = 311207743, +(8, 29) = 398796225, +(8, 30) = 506750351, +(8, 31) = 638878193, +(8, 32) = 799538175, +(8, 33) = 993696769, +(8, 34) = 1226990095, +(8, 35) = 1505789553, +(8, 36) = 1837271615, +(8, 37) = 2229491905, +(9, 0) = 0, +(9, 1) = 1, +(9, 2) = 17, +(9, 3) = 145, +(9, 4) = 833, +(9, 5) = 3649, +(9, 6) = 13073, +(9, 7) = 40081, +(9, 8) = 108545, +(9, 9) = 265729, +(9, 10) = 598417, +(9, 11) = 1256465, +(9, 12) = 2485825, +(9, 13) = 4673345, +(9, 14) = 8405905, +(9, 15) = 14546705, +(9, 16) = 24331777, +(9, 17) = 39490049, +(9, 18) = 62390545, +(9, 19) = 96220561, +(9, 20) = 145198913, +(9, 21) = 214828609, +(9, 22) = 312193553, +(9, 23) = 446304145, +(9, 24) = 628496897, +(9, 25) = 872893441, +(9, 26) = 1196924561, +(9, 27) = 1621925137, +(9, 28) = 2173806145, +(10, 0) = 0, +(10, 1) = 1, +(10, 2) = 19, +(10, 3) = 181, +(10, 4) = 1159, +(10, 5) = 5641, +(10, 6) = 22363, +(10, 7) = 75517, +(10, 8) = 224143, +(10, 9) = 598417, +(10, 10) = 1462563, +(10, 11) = 3317445, +(10, 12) = 7059735, +(10, 13) = 14218905, +(10, 14) = 27298155, +(10, 15) = 50250765, +(10, 16) = 89129247, +(10, 17) = 152951073, +(10, 18) = 254831667, +(10, 19) = 413442773, +(10, 20) = 654862247, +(10, 21) = 1014889769, +(10, 22) = 1541911931, +(10, 23) = 2300409629, +(10, 24) = 3375210671, +(11, 0) = 0, +(11, 1) = 1, +(11, 2) = 21, +(11, 3) = 221, +(11, 4) = 1561, +(11, 5) = 8361, +(11, 6) = 36365, +(11, 7) = 134245, +(11, 8) = 433905, +(11, 9) = 1256465, +(11, 10) = 3317445, +(11, 11) = 8097453, +(11, 12) = 18474633, +(11, 13) = 39753273, +(11, 14) = 81270333, +(11, 15) = 158819253, +(11, 16) = 298199265, +(11, 17) = 540279585, +(11, 18) = 948062325, +(11, 19) = 1616336765, +(12, 0) = 0, +(12, 1) = 1, +(12, 2) = 23, +(12, 3) = 265, +(12, 4) = 2047, +(12, 5) = 11969, +(12, 6) = 56695, +(12, 7) = 227305, +(12, 8) = 795455, +(12, 9) = 2485825, +(12, 10) = 7059735, +(12, 11) = 18474633, +(12, 12) = 45046719, +(12, 13) = 103274625, +(12, 14) = 224298231, +(12, 15) = 464387817, +(12, 16) = 921406335, +(12, 17) = 1759885185, +(12, 18) = 3248227095, +(13, 0) = 0, +(13, 1) = 1, +(13, 2) = 25, +(13, 3) = 313, +(13, 4) = 2625, +(13, 5) = 16641, +(13, 6) = 85305, +(13, 7) = 369305, +(13, 8) = 1392065, +(13, 9) = 4673345, +(13, 10) = 14218905, +(13, 11) = 39753273, +(13, 12) = 103274625, +(13, 13) = 251595969, +(13, 14) = 579168825, +(13, 15) = 1267854873, +(13, 16) = 2653649025, +(14, 0) = 0, +(14, 1) = 1, +(14, 2) = 27, +(14, 3) = 365, +(14, 4) = 3303, +(14, 5) = 22569, +(14, 6) = 124515, +(14, 7) = 579125, +(14, 8) = 2340495, +(14, 9) = 8405905, +(14, 10) = 27298155, +(14, 11) = 81270333, +(14, 12) = 224298231, +(14, 13) = 579168825, +(14, 14) = 1409933619, + diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_cwrs32.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_cwrs32.rs new file mode 100644 index 00000000..1e961fd0 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_cwrs32.rs @@ -0,0 +1,2684 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod arch_h { + pub type opus_val32 = f32; +} +pub mod entcode_h { + pub type ec_window = u32; + #[derive(Copy, Clone)] + #[repr(C)] + pub struct ec_ctx { + pub buf: *mut u8, + pub storage: u32, + pub end_offs: u32, + pub end_window: ec_window, + pub nend_bits: i32, + pub nbits_total: i32, + pub offs: u32, + pub rng: u32, + pub val: u32, + pub ext: u32, + pub rem: i32, + pub error: i32, + } + pub type ec_enc = ec_ctx; + pub type ec_dec = ec_ctx; + #[inline] + pub unsafe fn celt_udiv(mut n: u32, mut d: u32) -> u32 { + return n.wrapping_div(d); + } +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + pub fn printf(_: *const i8, _: ...) -> i32; + } +} +pub mod entenc_c { + pub unsafe fn ec_enc_done(mut _this: *mut ec_enc) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + let mut msk: u32 = 0; + let mut end: u32 = 0; + let mut l: i32 = 0; + l = 32 + - (::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32); + msk = ((1 as u32) << 32 - 1) + .wrapping_sub(1) + >> l; + end = ((*_this).val).wrapping_add(msk) & !msk; + if end | msk >= ((*_this).val).wrapping_add((*_this).rng) { + l += 1; + msk >>= 1; + end = ((*_this).val).wrapping_add(msk) & !msk; + } + while l > 0 { + ec_enc_carry_out( + _this, + (end >> 32 - 8 - 1) as i32, + ); + end = end << 8 + & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + l -= 8; + } + if (*_this).rem >= 0 || (*_this).ext > 0 { + ec_enc_carry_out(_this, 0); + } + window = (*_this).end_window; + used = (*_this).nend_bits; + while used >= 8 { + (*_this).error |= ec_write_byte_at_end( + _this, + window + & ((1 as u32) << 8) + .wrapping_sub(1), + ); + window >>= 8; + used -= 8; + } + if (*_this).error == 0 { + memset( + ((*_this).buf).offset((*_this).offs as isize) as *mut core::ffi::c_void, + 0, + (((*_this).storage) + .wrapping_sub((*_this).offs) + .wrapping_sub((*_this).end_offs) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + if used > 0 { + if (*_this).end_offs >= (*_this).storage { + (*_this).error = -1; + } else { + l = -l; + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage + && l < used + { + window &= (((1) << l) - 1) as u32; + (*_this).error = -1; + } + let ref mut fresh0 = *((*_this).buf).offset( + ((*_this).storage) + .wrapping_sub((*_this).end_offs) + .wrapping_sub(1) + as isize, + ); + *fresh0 = (*fresh0 as i32 | window as u8 as i32) + as u8; + } + } + } + } + pub unsafe fn ec_enc_shrink(mut _this: *mut ec_enc, mut _size: u32) { + memmove( + ((*_this).buf) + .offset(_size as isize) + .offset(-((*_this).end_offs as isize)) as *mut core::ffi::c_void, + ((*_this).buf) + .offset((*_this).storage as isize) + .offset(-((*_this).end_offs as isize)) as *const core::ffi::c_void, + ((*_this).end_offs as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 + * ((*_this).buf) + .offset(_size as isize) + .offset(-((*_this).end_offs as isize)) + .offset_from( + ((*_this).buf) + .offset((*_this).storage as isize) + .offset(-((*_this).end_offs as isize)), + ) as i64) as u64, + ), + ); + (*_this).storage = _size; + } + pub unsafe fn ec_enc_patch_initial_bits( + mut _this: *mut ec_enc, + mut _val: u32, + mut _nbits: u32, + ) { + let mut shift: i32 = 0; + let mut mask: u32 = 0; + shift = (8).wrapping_sub(_nbits) as i32; + mask = ((((1) << _nbits) - 1) << shift) as u32; + if (*_this).offs > 0 { + *((*_this).buf).offset(0 as isize) = + (*((*_this).buf).offset(0 as isize) as u32 & !mask + | _val << shift) as u8; + } else if (*_this).rem >= 0 { + (*_this).rem = ((*_this).rem as u32 & !mask | _val << shift) as i32; + } else if (*_this).rng + <= (1 as u32) << 32 - 1 >> _nbits + { + (*_this).val = (*_this).val + & !(mask << 32 - 8 - 1) + | _val << 32 - 8 - 1 + shift; + } else { + (*_this).error = -1; + }; + } + pub unsafe fn ec_write_byte_at_end( + mut _this: *mut ec_enc, + mut _value: u32, + ) -> i32 { + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage { + return -1; + } + (*_this).end_offs = ((*_this).end_offs).wrapping_add(1); + *((*_this).buf).offset(((*_this).storage).wrapping_sub((*_this).end_offs) as isize) = + _value as u8; + return 0; + } + pub unsafe fn ec_enc_bits( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _bits: u32, + ) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + window = (*_this).end_window; + used = (*_this).nend_bits; + if (used as u32).wrapping_add(_bits) + > (::core::mem::size_of::() as u64 as i32 + * 8) as u32 + { + loop { + (*_this).error |= ec_write_byte_at_end( + _this, + window + & ((1 as u32) << 8) + .wrapping_sub(1), + ); + window >>= 8; + used -= 8; + if !(used >= 8) { + break; + } + } + } + window |= _fl << used; + used = (used as u32).wrapping_add(_bits) as i32 as i32; + (*_this).end_window = window; + (*_this).nend_bits = used; + (*_this).nbits_total = ((*_this).nbits_total as u32).wrapping_add(_bits) + as i32 as i32; + } + pub unsafe fn ec_enc_uint(mut _this: *mut ec_enc, mut _fl: u32, mut _ft: u32) { + let mut ft: u32 = 0; + let mut fl: u32 = 0; + let mut ftb: i32 = 0; + _ft = _ft.wrapping_sub(1); + ftb = ::core::mem::size_of::() as u64 as i32 + * 8 + - _ft.leading_zeros() as i32; + if ftb > 8 { + ftb -= 8; + ft = (_ft >> ftb).wrapping_add(1); + fl = _fl >> ftb; + ec_encode( + _this, + fl, + fl.wrapping_add(1), + ft, + ); + ec_enc_bits( + _this, + _fl & ((1) << ftb).wrapping_sub(1 as u32), + ftb as u32, + ); + } else { + ec_encode( + _this, + _fl, + _fl.wrapping_add(1), + _ft.wrapping_add(1), + ); + }; + } + pub unsafe fn ec_enc_icdf( + mut _this: *mut ec_enc, + mut _s: i32, + mut _icdf: *const u8, + mut _ftb: u32, + ) { + let mut r: u32 = 0; + r = (*_this).rng >> _ftb; + if _s > 0 { + (*_this).val = ((*_this).val as u32).wrapping_add(((*_this).rng).wrapping_sub( + r.wrapping_mul(*_icdf.offset((_s - 1) as isize) as u32), + )) as u32 as u32; + (*_this).rng = r.wrapping_mul( + (*_icdf.offset((_s - 1) as isize) as i32 + - *_icdf.offset(_s as isize) as i32) as u32, + ); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(*_icdf.offset(_s as isize) as u32)) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_bit_logp( + mut _this: *mut ec_enc, + mut _val: i32, + mut _logp: u32, + ) { + let mut r: u32 = 0; + let mut s: u32 = 0; + let mut l: u32 = 0; + r = (*_this).rng; + l = (*_this).val; + s = r >> _logp; + r = (r as u32).wrapping_sub(s) as u32 as u32; + if _val != 0 { + (*_this).val = l.wrapping_add(r); + } + (*_this).rng = if _val != 0 { s } else { r }; + ec_enc_normalize(_this); + } + pub unsafe fn ec_encode_bin( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _fh: u32, + mut _bits: u32, + ) { + let mut r: u32 = 0; + r = (*_this).rng >> _bits; + if _fl > 0 { + (*_this).val = ((*_this).val as u32).wrapping_add( + ((*_this).rng) + .wrapping_sub(r.wrapping_mul(((1 as u32) << _bits).wrapping_sub(_fl))), + ) as u32 as u32; + (*_this).rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(((1 as u32) << _bits).wrapping_sub(_fh))) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_write_byte( + mut _this: *mut ec_enc, + mut _value: u32, + ) -> i32 { + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage { + return -1; + } + let fresh1 = (*_this).offs; + (*_this).offs = ((*_this).offs).wrapping_add(1); + *((*_this).buf).offset(fresh1 as isize) = _value as u8; + return 0; + } + pub unsafe fn ec_enc_carry_out(mut _this: *mut ec_enc, mut _c: i32) { + if _c as u32 + != ((1 as u32) << 8) + .wrapping_sub(1) + { + let mut carry: i32 = 0; + carry = _c >> 8; + if (*_this).rem >= 0 { + (*_this).error |= ec_write_byte(_this, ((*_this).rem + carry) as u32); + } + if (*_this).ext > 0 { + let mut sym: u32 = 0; + sym = ((1 as u32) << 8) + .wrapping_sub(1) + .wrapping_add(carry as u32) + & ((1 as u32) << 8) + .wrapping_sub(1); + loop { + (*_this).error |= ec_write_byte(_this, sym); + (*_this).ext = ((*_this).ext).wrapping_sub(1); + if !((*_this).ext > 0) { + break; + } + } + } + (*_this).rem = (_c as u32 + & ((1 as u32) << 8) + .wrapping_sub(1)) + as i32; + } else { + (*_this).ext = ((*_this).ext).wrapping_add(1); + }; + } + #[inline] + pub unsafe fn ec_enc_normalize(mut _this: *mut ec_enc) { + while (*_this).rng + <= (1 as u32) << 32 - 1 >> 8 + { + ec_enc_carry_out( + _this, + ((*_this).val >> 32 - 8 - 1) + as i32, + ); + (*_this).val = (*_this).val << 8 + & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + (*_this).rng <<= 8; + (*_this).nbits_total += 8; + } + } + pub unsafe fn ec_encode( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _fh: u32, + mut _ft: u32, + ) { + let mut r: u32 = 0; + r = celt_udiv((*_this).rng, _ft); + if _fl > 0 { + (*_this).val = ((*_this).val as u32) + .wrapping_add(((*_this).rng).wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fl)))) + as u32 as u32; + (*_this).rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fh))) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_init( + mut _this: *mut ec_enc, + mut _buf: *mut u8, + mut _size: u32, + ) { + (*_this).buf = _buf; + (*_this).end_offs = 0; + (*_this).end_window = 0 as ec_window; + (*_this).nend_bits = 0; + (*_this).nbits_total = 32 + 1; + (*_this).offs = 0; + (*_this).rng = (1 as u32) << 32 - 1; + (*_this).rem = -1; + (*_this).val = 0; + (*_this).ext = 0; + (*_this).storage = _size; + (*_this).error = 0; + } + use super::entcode_h::{celt_udiv, ec_enc, ec_window}; + use crate::externs::{memmove, memset}; +} +pub mod stdlib_h { + { + pub fn abs(_: i32) -> i32; + } +} +pub mod entdec_c { + pub unsafe fn ec_read_byte(mut _this: &mut ec_dec) -> i32 { + return if (*_this).offs < (*_this).storage { + let fresh2 = (*_this).offs; + (*_this).offs = ((*_this).offs).wrapping_add(1); + *((*_this).buf).offset(fresh2 as isize) as i32 + } else { + 0 + }; + } + pub unsafe fn ec_read_byte_from_end(mut _this: &mut ec_dec) -> i32 { + return if (*_this).end_offs < (*_this).storage { + (*_this).end_offs = ((*_this).end_offs).wrapping_add(1); + *((*_this).buf).offset(((*_this).storage).wrapping_sub((*_this).end_offs) as isize) + as i32 + } else { + 0 + }; + } + pub unsafe fn ec_dec_normalize(mut _this: &mut ec_dec) { + while (*_this).rng + <= (1 as u32) << 32 - 1 >> 8 + { + let mut sym: i32 = 0; + (*_this).nbits_total += 8; + (*_this).rng <<= 8; + sym = (*_this).rem; + (*_this).rem = ec_read_byte(_this); + sym = (sym << 8 | (*_this).rem) + >> 8 + - ((32 - 2) % 8 + + 1); + (*_this).val = ((*_this).val << 8).wrapping_add( + ((1 as u32) << 8) + .wrapping_sub(1) + & !sym as u32, + ) & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + } + } + pub unsafe fn ec_decode_bin( + mut _this: &mut ec_dec, + mut _bits: u32, + ) -> u32 { + let mut s: u32 = 0; + (*_this).ext = (*_this).rng >> _bits; + s = ((*_this).val).wrapping_div((*_this).ext); + return ((1 as u32) << _bits).wrapping_sub( + s.wrapping_add(1 as u32).wrapping_add( + ((1 as u32) << _bits).wrapping_sub(s.wrapping_add(1 as u32)) + & -(((1 as u32) << _bits < s.wrapping_add(1 as u32)) + as i32) as u32, + ), + ); + } + pub unsafe fn ec_dec_update( + mut _this: &mut ec_dec, + mut _fl: u32, + mut _fh: u32, + mut _ft: u32, + ) { + let mut s: u32 = 0; + s = ((*_this).ext).wrapping_mul(_ft.wrapping_sub(_fh)); + (*_this).val = ((*_this).val as u32).wrapping_sub(s) as u32 as u32; + (*_this).rng = if _fl > 0 { + ((*_this).ext).wrapping_mul(_fh.wrapping_sub(_fl)) + } else { + ((*_this).rng).wrapping_sub(s) + }; + ec_dec_normalize(_this); + } + pub unsafe fn ec_dec_bit_logp( + mut _this: &mut ec_dec, + mut _logp: u32, + ) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut ret: i32 = 0; + r = (*_this).rng; + d = (*_this).val; + s = r >> _logp; + ret = (d < s) as i32; + if ret == 0 { + (*_this).val = d.wrapping_sub(s); + } + (*_this).rng = if ret != 0 { s } else { r.wrapping_sub(s) }; + ec_dec_normalize(_this); + return ret; + } + pub unsafe fn ec_dec_icdf( + mut _this: &mut ec_dec, + mut _icdf: *const u8, + mut _ftb: u32, + ) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut t: u32 = 0; + let mut ret: i32 = 0; + s = (*_this).rng; + d = (*_this).val; + r = s >> _ftb; + ret = -1; + loop { + t = s; + ret += 1; + s = r.wrapping_mul(*_icdf.offset(ret as isize) as u32); + if !(d < s) { + break; + } + } + (*_this).val = d.wrapping_sub(s); + (*_this).rng = t.wrapping_sub(s); + ec_dec_normalize(_this); + return ret; + } + pub unsafe fn ec_dec_uint(mut _this: &mut ec_dec, mut _ft: u32) -> u32 { + let mut ft: u32 = 0; + let mut s: u32 = 0; + let mut ftb: i32 = 0; + _ft = _ft.wrapping_sub(1); + ftb = ::core::mem::size_of::() as u64 as i32 + * 8 + - _ft.leading_zeros() as i32; + if ftb > 8 { + let mut t: u32 = 0; + ftb -= 8; + ft = (_ft >> ftb).wrapping_add(1); + s = ec_decode(_this, ft); + ec_dec_update( + _this, + s, + s.wrapping_add(1), + ft, + ); + t = s << ftb | ec_dec_bits(_this, ftb as u32); + if t <= _ft { + return t; + } + (*_this).error = 1; + return _ft; + } else { + _ft = _ft.wrapping_add(1); + s = ec_decode(_this, _ft); + ec_dec_update( + _this, + s, + s.wrapping_add(1), + _ft, + ); + return s; + }; + } + pub unsafe fn ec_dec_bits(mut _this: &mut ec_dec, mut _bits: u32) -> u32 { + let mut window: ec_window = 0; + let mut available: i32 = 0; + let mut ret: u32 = 0; + window = (*_this).end_window; + available = (*_this).nend_bits; + if (available as u32) < _bits { + loop { + window |= (ec_read_byte_from_end(_this) as ec_window) << available; + available += 8; + if !(available + <= ::core::mem::size_of::() as u64 as i32 + * 8 + - 8) + { + break; + } + } + } + ret = window & ((1) << _bits).wrapping_sub(1 as u32); + window >>= _bits; + available = (available as u32).wrapping_sub(_bits) as i32 as i32; + (*_this).end_window = window; + (*_this).nend_bits = available; + (*_this).nbits_total = ((*_this).nbits_total as u32).wrapping_add(_bits) + as i32 as i32; + return ret; + } + pub unsafe fn ec_decode( + mut _this: &mut ec_dec, + mut _ft: u32, + ) -> u32 { + let mut s: u32 = 0; + (*_this).ext = celt_udiv((*_this).rng, _ft); + s = ((*_this).val).wrapping_div((*_this).ext); + return _ft.wrapping_sub( + s.wrapping_add(1) + .wrapping_add( + _ft.wrapping_sub(s.wrapping_add(1)) + & -((_ft < s.wrapping_add(1)) as i32) + as u32, + ), + ); + } + pub unsafe fn ec_dec_init( + mut _this: &mut ec_dec, + mut _buf: *mut u8, + mut _storage: u32, + ) { + (*_this).buf = _buf; + (*_this).storage = _storage; + (*_this).end_offs = 0; + (*_this).end_window = 0 as ec_window; + (*_this).nend_bits = 0; + (*_this).nbits_total = 32 + 1 + - (32 + - ((32 - 2) % 8 + 1)) + / 8 + * 8; + (*_this).offs = 0; + (*_this).rng = (1 as u32) + << (32 - 2) % 8 + 1; + (*_this).rem = ec_read_byte(_this); + (*_this).val = ((*_this).rng) + .wrapping_sub(1) + .wrapping_sub( + ((*_this).rem + >> 8 + - ((32 - 2) % 8 + + 1)) as u32, + ); + (*_this).error = 0; + ec_dec_normalize(_this); + } + use super::entcode_h::{celt_udiv, ec_dec, ec_window}; +} +pub mod entcode_c { + pub unsafe fn ec_tell_frac(mut _this: *mut ec_ctx) -> u32 { + pub static mut correction: [u32; 8] = [ + 35733, + 38967, + 42495, + 46340, + 50535, + 55109, + 60097, + 65535, + ]; + let mut nbits: u32 = 0; + let mut r: u32 = 0; + let mut l: i32 = 0; + let mut b: u32 = 0; + nbits = ((*_this).nbits_total << 3) as u32; + l = ::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32; + r = (*_this).rng >> l - 16; + b = (r >> 12).wrapping_sub(8); + b = b.wrapping_add((r > correction[b as usize]) as i32 as u32); + l = ((l << 3) as u32).wrapping_add(b) as i32; + return nbits.wrapping_sub(l as u32); + } + use super::entcode_h::ec_ctx; +} +pub mod cwrs_c { + pub unsafe fn log2_frac(mut val: u32, mut frac: i32) -> i32 { + let mut l: i32 = 0; + l = ::core::mem::size_of::() as u64 as i32 + * 8 + - val.leading_zeros() as i32; + if val & val.wrapping_sub(1) != 0 { + if l > 16 { + val = (val.wrapping_sub(1) >> l - 16) + .wrapping_add(1); + } else { + val <<= 16 - l; + } + l = (l - 1) << frac; + loop { + let mut b: i32 = 0; + b = (val >> 16) as i32; + l += b << frac; + val = val.wrapping_add(b as u32) >> b; + val = val + .wrapping_mul(val) + .wrapping_add(0x7fff) + >> 15; + let fresh3 = frac; + frac = frac - 1; + if !(fresh3 > 0) { + break; + } + } + return l + (val > 0x8000) as i32; + } else { + return (l - 1) << frac; + }; + } + pub static mut CELT_PVQ_U_DATA: [u32; 1488] = [ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63, + 65, + 67, + 69, + 71, + 73, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 95, + 97, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + 127, + 129, + 131, + 133, + 135, + 137, + 139, + 141, + 143, + 145, + 147, + 149, + 151, + 153, + 155, + 157, + 159, + 161, + 163, + 165, + 167, + 169, + 171, + 173, + 175, + 177, + 179, + 181, + 183, + 185, + 187, + 189, + 191, + 193, + 195, + 197, + 199, + 201, + 203, + 205, + 207, + 209, + 211, + 213, + 215, + 217, + 219, + 221, + 223, + 225, + 227, + 229, + 231, + 233, + 235, + 237, + 239, + 241, + 243, + 245, + 247, + 249, + 251, + 253, + 255, + 257, + 259, + 261, + 263, + 265, + 267, + 269, + 271, + 273, + 275, + 277, + 279, + 281, + 283, + 285, + 287, + 289, + 291, + 293, + 295, + 297, + 299, + 301, + 303, + 305, + 307, + 309, + 311, + 313, + 315, + 317, + 319, + 321, + 323, + 325, + 327, + 329, + 331, + 333, + 335, + 337, + 339, + 341, + 343, + 345, + 347, + 349, + 351, + 353, + 355, + 357, + 359, + 361, + 363, + 365, + 367, + 369, + 371, + 373, + 375, + 377, + 379, + 381, + 383, + 385, + 387, + 389, + 391, + 393, + 395, + 397, + 399, + 401, + 403, + 405, + 407, + 409, + 411, + 413, + 415, + 13, + 25, + 41, + 61, + 85, + 113, + 145, + 181, + 221, + 265, + 313, + 365, + 421, + 481, + 545, + 613, + 685, + 761, + 841, + 925, + 1013, + 1105, + 1201, + 1301, + 1405, + 1513, + 1625, + 1741, + 1861, + 1985, + 2113, + 2245, + 2381, + 2521, + 2665, + 2813, + 2965, + 3121, + 3281, + 3445, + 3613, + 3785, + 3961, + 4141, + 4325, + 4513, + 4705, + 4901, + 5101, + 5305, + 5513, + 5725, + 5941, + 6161, + 6385, + 6613, + 6845, + 7081, + 7321, + 7565, + 7813, + 8065, + 8321, + 8581, + 8845, + 9113, + 9385, + 9661, + 9941, + 10225, + 10513, + 10805, + 11101, + 11401, + 11705, + 12013, + 12325, + 12641, + 12961, + 13285, + 13613, + 13945, + 14281, + 14621, + 14965, + 15313, + 15665, + 16021, + 16381, + 16745, + 17113, + 17485, + 17861, + 18241, + 18625, + 19013, + 19405, + 19801, + 20201, + 20605, + 21013, + 21425, + 21841, + 22261, + 22685, + 23113, + 23545, + 23981, + 24421, + 24865, + 25313, + 25765, + 26221, + 26681, + 27145, + 27613, + 28085, + 28561, + 29041, + 29525, + 30013, + 30505, + 31001, + 31501, + 32005, + 32513, + 33025, + 33541, + 34061, + 34585, + 35113, + 35645, + 36181, + 36721, + 37265, + 37813, + 38365, + 38921, + 39481, + 40045, + 40613, + 41185, + 41761, + 42341, + 42925, + 43513, + 44105, + 44701, + 45301, + 45905, + 46513, + 47125, + 47741, + 48361, + 48985, + 49613, + 50245, + 50881, + 51521, + 52165, + 52813, + 53465, + 54121, + 54781, + 55445, + 56113, + 56785, + 57461, + 58141, + 58825, + 59513, + 60205, + 60901, + 61601, + 62305, + 63013, + 63725, + 64441, + 65161, + 65885, + 66613, + 67345, + 68081, + 68821, + 69565, + 70313, + 71065, + 71821, + 72581, + 73345, + 74113, + 74885, + 75661, + 76441, + 77225, + 78013, + 78805, + 79601, + 80401, + 81205, + 82013, + 82825, + 83641, + 84461, + 85285, + 86113, + 63, + 129, + 231, + 377, + 575, + 833, + 1159, + 1561, + 2047, + 2625, + 3303, + 4089, + 4991, + 6017, + 7175, + 8473, + 9919, + 11521, + 13287, + 15225, + 17343, + 19649, + 22151, + 24857, + 27775, + 30913, + 34279, + 37881, + 41727, + 45825, + 50183, + 54809, + 59711, + 64897, + 70375, + 76153, + 82239, + 88641, + 95367, + 102425, + 109823, + 117569, + 125671, + 134137, + 142975, + 152193, + 161799, + 171801, + 182207, + 193025, + 204263, + 215929, + 228031, + 240577, + 253575, + 267033, + 280959, + 295361, + 310247, + 325625, + 341503, + 357889, + 374791, + 392217, + 410175, + 428673, + 447719, + 467321, + 487487, + 508225, + 529543, + 551449, + 573951, + 597057, + 620775, + 645113, + 670079, + 695681, + 721927, + 748825, + 776383, + 804609, + 833511, + 863097, + 893375, + 924353, + 956039, + 988441, + 1021567, + 1055425, + 1090023, + 1125369, + 1161471, + 1198337, + 1235975, + 1274393, + 1313599, + 1353601, + 1394407, + 1436025, + 1478463, + 1521729, + 1565831, + 1610777, + 1656575, + 1703233, + 1750759, + 1799161, + 1848447, + 1898625, + 1949703, + 2001689, + 2054591, + 2108417, + 2163175, + 2218873, + 2275519, + 2333121, + 2391687, + 2451225, + 2511743, + 2573249, + 2635751, + 2699257, + 2763775, + 2829313, + 2895879, + 2963481, + 3032127, + 3101825, + 3172583, + 3244409, + 3317311, + 3391297, + 3466375, + 3542553, + 3619839, + 3698241, + 3777767, + 3858425, + 3940223, + 4023169, + 4107271, + 4192537, + 4278975, + 4366593, + 4455399, + 4545401, + 4636607, + 4729025, + 4822663, + 4917529, + 5013631, + 5110977, + 5209575, + 5309433, + 5410559, + 5512961, + 5616647, + 5721625, + 5827903, + 5935489, + 6044391, + 6154617, + 6266175, + 6379073, + 6493319, + 6608921, + 6725887, + 6844225, + 6963943, + 7085049, + 7207551, + 7331457, + 7456775, + 7583513, + 7711679, + 7841281, + 7972327, + 8104825, + 8238783, + 8374209, + 8511111, + 8649497, + 8789375, + 8930753, + 9073639, + 9218041, + 9363967, + 9511425, + 9660423, + 9810969, + 9963071, + 10116737, + 10271975, + 10428793, + 10587199, + 10747201, + 10908807, + 11072025, + 11236863, + 11403329, + 11571431, + 11741177, + 11912575, + 321, + 681, + 1289, + 2241, + 3649, + 5641, + 8361, + 11969, + 16641, + 22569, + 29961, + 39041, + 50049, + 63241, + 78889, + 97281, + 118721, + 143529, + 172041, + 204609, + 241601, + 283401, + 330409, + 383041, + 441729, + 506921, + 579081, + 658689, + 746241, + 842249, + 947241, + 1061761, + 1186369, + 1321641, + 1468169, + 1626561, + 1797441, + 1981449, + 2179241, + 2391489, + 2618881, + 2862121, + 3121929, + 3399041, + 3694209, + 4008201, + 4341801, + 4695809, + 5071041, + 5468329, + 5888521, + 6332481, + 6801089, + 7295241, + 7815849, + 8363841, + 8940161, + 9545769, + 10181641, + 10848769, + 11548161, + 12280841, + 13047849, + 13850241, + 14689089, + 15565481, + 16480521, + 17435329, + 18431041, + 19468809, + 20549801, + 21675201, + 22846209, + 24064041, + 25329929, + 26645121, + 28010881, + 29428489, + 30899241, + 32424449, + 34005441, + 35643561, + 37340169, + 39096641, + 40914369, + 42794761, + 44739241, + 46749249, + 48826241, + 50971689, + 53187081, + 55473921, + 57833729, + 60268041, + 62778409, + 65366401, + 68033601, + 70781609, + 73612041, + 76526529, + 79526721, + 82614281, + 85790889, + 89058241, + 92418049, + 95872041, + 99421961, + 103069569, + 106816641, + 110664969, + 114616361, + 118672641, + 122835649, + 127107241, + 131489289, + 135983681, + 140592321, + 145317129, + 150160041, + 155123009, + 160208001, + 165417001, + 170752009, + 176215041, + 181808129, + 187533321, + 193392681, + 199388289, + 205522241, + 211796649, + 218213641, + 224775361, + 231483969, + 238341641, + 245350569, + 252512961, + 259831041, + 267307049, + 274943241, + 282741889, + 290705281, + 298835721, + 307135529, + 315607041, + 324252609, + 333074601, + 342075401, + 351257409, + 360623041, + 370174729, + 379914921, + 389846081, + 399970689, + 410291241, + 420810249, + 431530241, + 442453761, + 453583369, + 464921641, + 476471169, + 488234561, + 500214441, + 512413449, + 524834241, + 537479489, + 550351881, + 563454121, + 576788929, + 590359041, + 604167209, + 618216201, + 632508801, + 647047809, + 661836041, + 676876329, + 692171521, + 707724481, + 723538089, + 739615241, + 755958849, + 772571841, + 789457161, + 806617769, + 824056641, + 841776769, + 859781161, + 878072841, + 896654849, + 915530241, + 934702089, + 954173481, + 973947521, + 994027329, + 1014416041, + 1035116809, + 1056132801, + 1077467201, + 1099123209, + 1121104041, + 1143412929, + 1166053121, + 1189027881, + 1212340489, + 1235994241, + 1683, + 3653, + 7183, + 13073, + 22363, + 36365, + 56695, + 85305, + 124515, + 177045, + 246047, + 335137, + 448427, + 590557, + 766727, + 982729, + 1244979, + 1560549, + 1937199, + 2383409, + 2908411, + 3522221, + 4235671, + 5060441, + 6009091, + 7095093, + 8332863, + 9737793, + 11326283, + 13115773, + 15124775, + 17372905, + 19880915, + 22670725, + 25765455, + 29189457, + 32968347, + 37129037, + 41699767, + 46710137, + 52191139, + 58175189, + 64696159, + 71789409, + 79491819, + 87841821, + 96879431, + 106646281, + 117185651, + 128542501, + 140763503, + 153897073, + 167993403, + 183104493, + 199284183, + 216588185, + 235074115, + 254801525, + 275831935, + 298228865, + 322057867, + 347386557, + 374284647, + 402823977, + 433078547, + 465124549, + 499040399, + 534906769, + 572806619, + 612825229, + 655050231, + 699571641, + 746481891, + 795875861, + 847850911, + 902506913, + 959946283, + 1020274013, + 1083597703, + 1150027593, + 1219676595, + 1292660325, + 1369097135, + 1449108145, + 1532817275, + 1620351277, + 1711839767, + 1807415257, + 1907213187, + 2011371957, + 2120032959, + 2233340609 as u32, + 2351442379 as u32, + 2474488829 as u32, + 2602633639 as u32, + 2736033641 as u32, + 2874848851 as u32, + 3019242501 as u32, + 3169381071 as u32, + 3325434321 as u32, + 3487575323 as u32, + 3655980493 as u32, + 3830829623 as u32, + 4012305913 as u32, + 8989, + 19825, + 40081, + 75517, + 134245, + 227305, + 369305, + 579125, + 880685, + 1303777, + 1884961, + 2668525, + 3707509, + 5064793, + 6814249, + 9041957, + 11847485, + 15345233, + 19665841, + 24957661, + 31388293, + 39146185, + 48442297, + 59511829, + 72616013, + 88043969, + 106114625, + 127178701, + 151620757, + 179861305, + 212358985, + 249612805, + 292164445, + 340600625, + 395555537, + 457713341, + 527810725, + 606639529, + 695049433, + 793950709, + 904317037, + 1027188385, + 1163673953, + 1314955181, + 1482288821, + 1667010073, + 1870535785, + 2094367717, + 2340095869 as u32, + 2609401873 as u32, + 2904062449 as u32, + 3225952925 as u32, + 3577050821 as u32, + 3959439497 as u32, + 48639, + 108545, + 224143, + 433905, + 795455, + 1392065, + 2340495, + 3800305, + 5984767, + 9173505, + 13726991, + 20103025, + 28875327, + 40754369, + 56610575, + 77500017, + 104692735, + 139703809, + 184327311, + 240673265, + 311207743, + 398796225, + 506750351, + 638878193, + 799538175, + 993696769, + 1226990095, + 1505789553, + 1837271615, + 2229491905 as u32, + 2691463695 as u32, + 3233240945 as u32, + 3866006015 as u32, + 265729, + 598417, + 1256465, + 2485825, + 4673345, + 8405905, + 14546705, + 24331777, + 39490049, + 62390545, + 96220561, + 145198913, + 214828609, + 312193553, + 446304145, + 628496897, + 872893441, + 1196924561, + 1621925137, + 2173806145 as u32, + 2883810113 as u32, + 1462563, + 3317445, + 7059735, + 14218905, + 27298155, + 50250765, + 89129247, + 152951073, + 254831667, + 413442773, + 654862247, + 1014889769, + 1541911931, + 2300409629 as u32, + 3375210671 as u32, + 8097453, + 18474633, + 39753273, + 81270333, + 158819253, + 298199265, + 540279585, + 948062325, + 1616336765, + 2684641785 as u32, + 45046719, + 103274625, + 224298231, + 464387817, + 921406335, + 1759885185, + 3248227095 as u32, + 251595969, + 579168825, + 1267854873, + 2653649025 as u32, + 1409933619, + ]; + pub static mut CELT_PVQ_U_ROW: [*const u32; 15] = unsafe { [ + CELT_PVQ_U_DATA.as_ptr().offset(0 as isize), + CELT_PVQ_U_DATA.as_ptr().offset(208 as isize), + CELT_PVQ_U_DATA.as_ptr().offset(415 as isize), + CELT_PVQ_U_DATA.as_ptr().offset(621 as isize), + CELT_PVQ_U_DATA.as_ptr().offset(826 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1030 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1233 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1336 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1389 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1421 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1441 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1455 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1464 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1470 as isize), + CELT_PVQ_U_DATA + .as_ptr() + .offset(1473 as isize), + ] }; + pub unsafe fn get_required_bits( + mut _bits: *mut i16, + mut _n: i32, + mut _maxk: i32, + mut _frac: i32, + ) { + let mut k: i32 = 0; + *_bits.offset(0 as isize) = 0; + k = 1; + while k <= _maxk { + *_bits.offset(k as isize) = log2_frac( + (*(CELT_PVQ_U_ROW[(if _n < k { _n } else { k }) as usize]) + .offset((if _n > k { _n } else { k }) as isize)) + .wrapping_add( + *(CELT_PVQ_U_ROW[(if _n < k + 1 { + _n + } else { + k + 1 + }) as usize]) + .offset( + (if _n > k + 1 { + _n + } else { + k + 1 + }) as isize, + ), + ), + _frac, + ) as i16; + k += 1; + } + } + pub unsafe fn icwrs(mut _n: i32, mut _y: *const i32) -> u32 { + let mut i: u32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + j = _n - 1; + i = (*_y.offset(j as isize) < 0) as i32 as u32; + k = abs(*_y.offset(j as isize)); + loop { + j -= 1; + i = (i as u32).wrapping_add( + *(CELT_PVQ_U_ROW[(if _n - j < k { _n - j } else { k }) as usize]) + .offset((if _n - j > k { _n - j } else { k }) as isize), + ) as u32 as u32; + k += abs(*_y.offset(j as isize)); + if *_y.offset(j as isize) < 0 { + i = (i as u32).wrapping_add( + *(CELT_PVQ_U_ROW[(if _n - j < k + 1 { + _n - j + } else { + k + 1 + }) as usize]) + .offset( + (if _n - j > k + 1 { + _n - j + } else { + k + 1 + }) as isize, + ), + ) as u32 as u32; + } + if !(j > 0) { + break; + } + } + return i; + } + pub unsafe fn encode_pulses( + mut _y: *const i32, + mut _n: i32, + mut _k: i32, + mut _enc: *mut ec_enc, + ) { + ec_enc_uint( + _enc, + icwrs(_n, _y), + (*(CELT_PVQ_U_ROW[(if _n < _k { _n } else { _k }) as usize]) + .offset((if _n > _k { _n } else { _k }) as isize)) + .wrapping_add( + *(CELT_PVQ_U_ROW[(if _n < _k + 1 { + _n + } else { + _k + 1 + }) as usize]) + .offset( + (if _n > _k + 1 { + _n + } else { + _k + 1 + }) as isize, + ), + ), + ); + } + pub unsafe fn cwrsi( + mut _n: i32, + mut _k: i32, + mut _i: u32, + mut _y: *mut i32, + ) -> opus_val32 { + let mut p: u32 = 0; + let mut s: i32 = 0; + let mut k0: i32 = 0; + let mut val: i16 = 0; + let mut yy: opus_val32 = 0 as opus_val32; + while _n > 2 { + let mut q: u32 = 0; + if _k >= _n { + let mut row: *const u32 = 0 as *const u32; + row = CELT_PVQ_U_ROW[_n as usize]; + p = *row.offset((_k + 1) as isize); + s = -((_i >= p) as i32); + _i = (_i as u32).wrapping_sub(p & s as u32) as u32 as u32; + k0 = _k; + q = *row.offset(_n as isize); + if q > _i { + _k = _n; + loop { + _k -= 1; + p = *(CELT_PVQ_U_ROW[_k as usize]).offset(_n as isize); + if !(p > _i) { + break; + } + } + } else { + p = *row.offset(_k as isize); + while p > _i { + _k -= 1; + p = *row.offset(_k as isize); + } + } + _i = (_i as u32).wrapping_sub(p) as u32 as u32; + val = (k0 - _k + s ^ s) as i16; + let fresh4 = _y; + _y = _y.offset(1); + *fresh4 = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + } else { + p = *(CELT_PVQ_U_ROW[_k as usize]).offset(_n as isize); + q = *(CELT_PVQ_U_ROW[(_k + 1) as usize]).offset(_n as isize); + if p <= _i && _i < q { + _i = (_i as u32).wrapping_sub(p) as u32 as u32; + let fresh5 = _y; + _y = _y.offset(1); + *fresh5 = 0; + } else { + s = -((_i >= q) as i32); + _i = (_i as u32).wrapping_sub(q & s as u32) as u32 as u32; + k0 = _k; + loop { + _k -= 1; + p = *(CELT_PVQ_U_ROW[_k as usize]).offset(_n as isize); + if !(p > _i) { + break; + } + } + _i = (_i as u32).wrapping_sub(p) as u32 as u32; + val = (k0 - _k + s ^ s) as i16; + let fresh6 = _y; + _y = _y.offset(1); + *fresh6 = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + } + } + _n -= 1; + } + p = (2 * _k + 1) as u32; + s = -((_i >= p) as i32); + _i = (_i as u32).wrapping_sub(p & s as u32) as u32 as u32; + k0 = _k; + _k = (_i.wrapping_add(1) >> 1) as i32; + if _k != 0 { + _i = (_i as u32) + .wrapping_sub((2 * _k - 1) as u32) + as u32 as u32; + } + val = (k0 - _k + s ^ s) as i16; + let fresh7 = _y; + _y = _y.offset(1); + *fresh7 = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + s = -(_i as i32); + val = (_k + s ^ s) as i16; + *_y = val as i32; + yy = yy + val as opus_val32 * val as opus_val32; + return yy; + } + pub unsafe fn decode_pulses( + mut _y: *mut i32, + mut _n: i32, + mut _k: i32, + mut _dec: &mut ec_dec, + ) -> opus_val32 { + return cwrsi( + _n, + _k, + ec_dec_uint( + _dec, + (*(CELT_PVQ_U_ROW[(if _n < _k { _n } else { _k }) as usize]) + .offset((if _n > _k { _n } else { _k }) as isize)) + .wrapping_add( + *(CELT_PVQ_U_ROW[(if _n < _k + 1 { + _n + } else { + _k + 1 + }) as usize]) + .offset( + (if _n > _k + 1 { + _n + } else { + _k + 1 + }) as isize, + ), + ), + ), + _y, + ); + } + use super::arch_h::opus_val32; + use super::entcode_h::{ec_dec, ec_enc}; + use super::entdec_c::ec_dec_uint; + use super::entenc_c::ec_enc_uint; + use super::stdlib_h::abs; +} +pub mod mathops_c { + pub unsafe fn isqrt32(mut _val: u32) -> u32 { + let mut b: u32 = 0; + let mut g: u32 = 0; + let mut bshift: i32 = 0; + g = 0; + bshift = ::core::mem::size_of::() as u64 as i32 + * 8 + - _val.leading_zeros() as i32 + - 1 + >> 1; + b = (1 as u32) << bshift; + loop { + let mut t: u32 = 0; + t = (g << 1).wrapping_add(b) << bshift; + if t <= _val { + g = g.wrapping_add(b); + _val = (_val as u32).wrapping_sub(t) as u32 as u32; + } + b >>= 1; + bshift -= 1; + if !(bshift >= 0) { + break; + } + } + return g; + } +} +pub mod rate_h { + #[inline] + pub unsafe fn get_pulses(mut i: i32) -> i32 { + return if i < 8 { + i + } else { + 8 + (i & 7) << (i >> 3) - 1 + }; + } +} +pub use self::arch_h::opus_val32; +pub use self::cwrs_c::{ + cwrsi, decode_pulses, encode_pulses, get_required_bits, icwrs, log2_frac, CELT_PVQ_U_DATA, + CELT_PVQ_U_ROW, +}; +pub use self::entcode_c::ec_tell_frac; +pub use self::entcode_h::{celt_udiv, ec_ctx, ec_dec, ec_enc, ec_window}; +pub use self::entdec_c::{ + ec_dec_bit_logp, ec_dec_bits, ec_dec_icdf, ec_dec_init, ec_dec_normalize, ec_dec_uint, + ec_dec_update, ec_decode, ec_decode_bin, ec_read_byte, ec_read_byte_from_end, +}; +pub use self::entenc_c::{ + ec_enc_bit_logp, ec_enc_bits, ec_enc_carry_out, ec_enc_done, ec_enc_icdf, ec_enc_init, + ec_enc_normalize, ec_enc_patch_initial_bits, ec_enc_shrink, ec_enc_uint, ec_encode, + ec_encode_bin, ec_write_byte, ec_write_byte_at_end, +}; +pub use self::mathops_c::isqrt32; +pub use self::rate_h::get_pulses; +pub use self::stddef_h::size_t; + +use self::stdio_h::{fprintf, printf, stderr}; +use self::stdlib_h::abs; +pub use self::struct_FILE_h::{_IO_codecvt, _IO_lock_t, _IO_marker, _IO_wide_data, _IO_FILE}; + +pub use self::FILE_h::FILE; +use crate::externs::{memmove, memset}; +static mut pn: [i32; 22] = [ + 2, + 3, + 4, + 6, + 8, + 9, + 11, + 12, + 16, + 18, + 22, + 24, + 32, + 36, + 44, + 48, + 64, + 72, + 88, + 96, + 144, + 176, +]; +static mut pkmax: [i32; 22] = [ + 128, + 128, + 128, + 88, + 36, + 26, + 18, + 16, + 12, + 11, + 9, + 9, + 7, + 7, + 6, + 6, + 5, + 5, + 5, + 5, + 4, + 4, +]; +unsafe fn main_0() -> i32 { + let mut t: i32 = 0; + let mut n: i32 = 0; + t = 0; + while t < 22 { + let mut pseudo: i32 = 0; + n = pn[t as usize]; + pseudo = 1; + while pseudo < 41 { + let mut k: i32 = 0; + let mut inc: u32 = 0; + let mut nc: u32 = 0; + let mut i: u32 = 0; + k = get_pulses(pseudo); + if k > pkmax[t as usize] { + break; + } + printf( + b"Testing CWRS with N=%i, K=%i...\n\0" as *const u8 as *const i8, + n, + k, + ); + nc = (*(CELT_PVQ_U_ROW[(if n < k { n } else { k }) as usize]) + .offset((if n > k { n } else { k }) as isize)) + .wrapping_add( + *(CELT_PVQ_U_ROW[(if n < k + 1 { + n + } else { + k + 1 + }) as usize]) + .offset( + (if n > k + 1 { + n + } else { + k + 1 + }) as isize, + ), + ); + inc = nc.wrapping_div(20000); + if inc < 1 { + inc = 1; + } + i = 0; + while i < nc { + let mut y: [i32; 240] = [0; 240]; + let mut sy: i32 = 0; + let mut v: u32 = 0; + let mut ii: u32 = 0; + let mut j: i32 = 0; + cwrsi(n, k, i, y.as_mut_ptr()); + sy = 0; + j = 0; + while j < n { + sy += abs(y[j as usize]); + j += 1; + } + if sy != k { + fprintf( + stderr(), + b"N=%d Pulse count mismatch in cwrsi (%d!=%d).\n\0" as *const u8 + as *const i8, + n, + sy, + k, + ); + return 99; + } + ii = icwrs(n, y.as_mut_ptr()); + v = (*(CELT_PVQ_U_ROW[(if n < k { n } else { k }) as usize]) + .offset((if n > k { n } else { k }) as isize)) + .wrapping_add( + *(CELT_PVQ_U_ROW[(if n < k + 1 { + n + } else { + k + 1 + }) as usize]) + .offset( + (if n > k + 1 { + n + } else { + k + 1 + }) as isize, + ), + ); + if ii != i { + fprintf( + stderr(), + b"Combination-index mismatch (%lu!=%lu).\n\0" as *const u8 + as *const i8, + ii as i64, + i as i64, + ); + return 1; + } + if v != nc { + fprintf( + stderr(), + b"Combination count mismatch (%lu!=%lu).\n\0" as *const u8 + as *const i8, + v as i64, + nc as i64, + ); + return 2; + } + i = (i as u32).wrapping_add(inc) as u32 as u32; + } + pseudo += 1; + } + t += 1; + } + return 0; +} +pub fn main() { + unsafe { ::std::process::exit(main_0() as i32) } +} \ No newline at end of file diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_dft.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_dft.rs new file mode 100644 index 00000000..e406b58f --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_dft.rs @@ -0,0 +1,326 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod arch_h { + pub type opus_val16 = f32; +} +pub mod kiss_fft_h { + #[derive(Copy, Clone)] + #[repr(C)] + pub struct kiss_fft_cpx { + pub r: f32, + pub i: f32, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct kiss_twiddle_cpx { + pub r: f32, + pub i: f32, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct arch_fft_state { + pub is_supported: i32, + pub priv_0: *mut core::ffi::c_void, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct kiss_fft_state { + pub nfft: i32, + pub scale: opus_val16, + pub shift: i32, + pub factors: [i16; 16], + pub bitrev: *const i16, + pub twiddles: *const kiss_twiddle_cpx, + pub arch_fft: *mut arch_fft_state, + } + use super::arch_h::opus_val16; + { + pub fn opus_fft_c( + cfg: *const kiss_fft_state, + fin: *const kiss_fft_cpx, + fout: *mut kiss_fft_cpx, + ); + pub fn opus_ifft_c( + cfg: *const kiss_fft_state, + fin: *const kiss_fft_cpx, + fout: *mut kiss_fft_cpx, + ); + } +} +pub mod modes_h { + #[derive(Copy, Clone)] + #[repr(C)] + pub struct OpusCustomMode { + pub Fs: i32, + pub overlap: i32, + pub nbEBands: i32, + pub effEBands: i32, + pub preemph: [opus_val16; 4], + pub eBands: *const i16, + pub maxLM: i32, + pub nbShortMdcts: i32, + pub shortMdctSize: i32, + pub nbAllocVectors: i32, + pub allocVectors: *const u8, + pub logN: *const i16, + pub window: *const opus_val16, + pub mdct: mdct_lookup, + pub cache: PulseCache, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct PulseCache { + pub size: i32, + pub index: *const i16, + pub bits: *const u8, + pub caps: *const u8, + } + use super::arch_h::opus_val16; + use crate::celt::mdct::mdct_lookup; +} +pub mod mdct_h { + #[derive(Copy, Clone)] + #[repr(C)] + pub struct mdct_lookup { + pub n: i32, + pub maxshift: i32, + pub kfft: [*const kiss_fft_state; 4], + pub trig: *const f32, + } + use super::kiss_fft_h::kiss_fft_state; +} +pub mod stdio_h { + { + pub fn printf(_: *const i8, _: ...) -> i32; + } +} +pub mod mathcalls_h { + { + pub fn cos(_: f64) -> f64; + pub fn sin(_: f64) -> f64; + pub fn log10(_: f64) -> f64; + } +} +pub mod stdlib_h { + #[inline] + pub unsafe fn atoi(mut __nptr: *const i8) -> i32 { + return strtol( + __nptr, + 0 as *mut core::ffi::c_void as *mut *mut i8, + 10, + ) as i32; + } + { + pub fn free(_: *mut core::ffi::c_void); + pub fn malloc(_: u64) -> *mut core::ffi::c_void; + pub fn rand() -> i32; + pub fn strtol( + _: *const i8, + _: *mut *mut i8, + _: i32, + ) -> i64; + } +} +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub mod opus_custom_h { + use super::modes_h::OpusCustomMode; + { + pub fn opus_custom_mode_create( + Fs: i32, + frame_size: i32, + error: *mut i32, + ) -> *mut OpusCustomMode; + } +} +pub use self::arch_h::opus_val16; +pub use self::cpu_support_h::opus_select_arch; +pub use self::kiss_fft_h::{ + arch_fft_state, kiss_fft_cpx, kiss_fft_state, kiss_twiddle_cpx, opus_fft_c, opus_ifft_c, +}; +use self::mathcalls_h::{cos, log10, sin}; +pub use self::modes_h::{OpusCustomMode, PulseCache}; +use self::opus_custom_h::opus_custom_mode_create; +pub use self::stddef_h::size_t; +use crate::celt::mdct::mdct_lookup; + +use self::stdio_h::printf; +pub use self::stdlib_h::{atoi, free, malloc, rand, strtol}; + +pub static mut ret: i32 = 0; +pub unsafe fn check( + mut in_0: *mut kiss_fft_cpx, + mut out: *mut kiss_fft_cpx, + mut nfft: i32, + mut isinverse: i32, +) { + let mut bin: i32 = 0; + let mut k: i32 = 0; + let mut errpow: f64 = 0 as f64; + let mut sigpow: f64 = 0 as f64; + let mut snr: f64 = 0.; + bin = 0; + while bin < nfft { + let mut ansr: f64 = 0 as f64; + let mut ansi: f64 = 0 as f64; + let mut difr: f64 = 0.; + let mut difi: f64 = 0.; + k = 0; + while k < nfft { + let mut phase: f64 = -(2) as f64 + * 3.14159265358979323846f64 + * bin as f64 + * k as f64 + / nfft as f64; + let mut re: f64 = cos(phase); + let mut im: f64 = sin(phase); + if isinverse != 0 { + im = -im; + } + if isinverse == 0 { + re /= nfft as f64; + im /= nfft as f64; + } + ansr += (*in_0.offset(k as isize)).r as f64 * re + - (*in_0.offset(k as isize)).i as f64 * im; + ansi += (*in_0.offset(k as isize)).r as f64 * im + + (*in_0.offset(k as isize)).i as f64 * re; + k += 1; + } + difr = ansr - (*out.offset(bin as isize)).r as f64; + difi = ansi - (*out.offset(bin as isize)).i as f64; + errpow += difr * difr + difi * difi; + sigpow += ansr * ansr + ansi * ansi; + bin += 1; + } + snr = 10 as f64 * log10(sigpow / errpow); + printf( + b"nfft=%d inverse=%d,snr = %f\n\0" as *const u8 as *const i8, + nfft, + isinverse, + snr, + ); + if snr < 60 as f64 { + printf( + b"** poor snr: %f ** \n\0" as *const u8 as *const i8, + snr, + ); + ret = 1; + } +} +pub unsafe fn test1d( + mut nfft: i32, + mut isinverse: i32, + mut arch: i32, +) { + let mut buflen: size_t = (::core::mem::size_of::() as u64) + .wrapping_mul(nfft as u64); + let mut in_0: *mut kiss_fft_cpx = 0 as *mut kiss_fft_cpx; + let mut out: *mut kiss_fft_cpx = 0 as *mut kiss_fft_cpx; + let mut k: i32 = 0; + let mut id: i32 = 0; + let mut cfg: *const kiss_fft_state = 0 as *const kiss_fft_state; + let mut mode: *mut OpusCustomMode = opus_custom_mode_create( + 48000, + 960, + 0 as *mut i32, + ); + if nfft == 480 { + id = 0; + } else if nfft == 240 { + id = 1; + } else if nfft == 120 { + id = 2; + } else if nfft == 60 { + id = 3; + } else { + return; + } + cfg = (*mode).mdct.kfft[id as usize]; + in_0 = malloc(buflen) as *mut kiss_fft_cpx; + out = malloc(buflen) as *mut kiss_fft_cpx; + k = 0; + while k < nfft { + (*in_0.offset(k as isize)).r = + (rand() % 32767 - 16384) as f32; + (*in_0.offset(k as isize)).i = + (rand() % 32767 - 16384) as f32; + k += 1; + } + k = 0; + while k < nfft { + (*in_0.offset(k as isize)).r *= 32768 as f32; + (*in_0.offset(k as isize)).i *= 32768 as f32; + k += 1; + } + if isinverse != 0 { + k = 0; + while k < nfft { + (*in_0.offset(k as isize)).r /= nfft as f32; + (*in_0.offset(k as isize)).i /= nfft as f32; + k += 1; + } + } + if isinverse != 0 { + opus_ifft_c(cfg, in_0, out); + } else { + opus_fft_c(cfg, in_0, out); + } + check(in_0, out, nfft, isinverse); + free(in_0 as *mut core::ffi::c_void); + free(out as *mut core::ffi::c_void); +} +unsafe fn main_0(mut argc: i32, mut argv: *mut *mut i8) -> i32 { + let mut arch: i32 = opus_select_arch(); + if argc > 1 { + let mut k: i32 = 0; + k = 1; + while k < argc { + test1d(atoi(*argv.offset(k as isize)), 0, arch); + test1d(atoi(*argv.offset(k as isize)), 1, arch); + k += 1; + } + } else { + test1d(32, 0, arch); + test1d(32, 1, arch); + test1d(128, 0, arch); + test1d(128, 1, arch); + test1d(256, 0, arch); + test1d(256, 1, arch); + test1d(36, 0, arch); + test1d(36, 1, arch); + test1d(50, 0, arch); + test1d(50, 1, arch); + test1d(60, 0, arch); + test1d(60, 1, arch); + test1d(120, 0, arch); + test1d(120, 1, arch); + test1d(240, 0, arch); + test1d(240, 1, arch); + test1d(480, 0, arch); + test1d(480, 1, arch); + } + return ret; +} +pub fn main() { + let mut args: Vec<*mut i8> = Vec::new(); + for arg in ::std::env::args() { + args.push( + (::std::ffi::CString::new(arg)) + .expect("Failed to convert argument into CString.") + .into_raw(), + ); + } + args.push(::core::ptr::null_mut()); + unsafe { + ::std::process::exit(main_0( + (args.len() - 1) as i32, + args.as_mut_ptr() as *mut *mut i8, + ) as i32) + } +} diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_entropy.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_entropy.rs new file mode 100644 index 00000000..412ae4b9 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_entropy.rs @@ -0,0 +1,1423 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod time_t_h { + pub type time_t = __time_t; +} +pub mod entcode_h { + pub type ec_window = u32; + #[derive(Copy, Clone)] + #[repr(C)] + pub struct ec_ctx { + pub buf: *mut u8, + pub storage: u32, + pub end_offs: u32, + pub end_window: ec_window, + pub nend_bits: i32, + pub nbits_total: i32, + pub offs: u32, + pub rng: u32, + pub val: u32, + pub ext: u32, + pub rem: i32, + pub error: i32, + } + pub type ec_enc = ec_ctx; + pub type ec_dec = ec_ctx; + #[inline] + pub unsafe fn ec_range_bytes(mut _this: *mut ec_ctx) -> u32 { + return (*_this).offs; + } + #[inline] + pub unsafe fn ec_tell(mut _this: *mut ec_ctx) -> i32 { + return (*_this).nbits_total + - (::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32); + } + #[inline] + pub unsafe fn celt_udiv(mut n: u32, mut d: u32) -> u32 { + return n.wrapping_div(d); + } +} +pub mod stdlib_h { + #[inline] + pub unsafe fn atoi(mut __nptr: *const i8) -> i32 { + return strtol( + __nptr, + 0 as *mut core::ffi::c_void as *mut *mut i8, + 10, + ) as i32; + } + { + pub fn strtol( + _: *const i8, + _: *mut *mut i8, + _: i32, + ) -> i64; + pub fn rand() -> i32; + pub fn srand(__seed: u32); + pub fn malloc(_: u64) -> *mut core::ffi::c_void; + pub fn free(_: *mut core::ffi::c_void); + pub fn getenv(__name: *const i8) -> *mut i8; + } +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + } +} +pub mod mathcalls_h { + { + pub fn ldexp(_: f64, _: i32) -> f64; + pub fn log(_: f64) -> f64; + } +} +pub mod time_h { + use super::time_t_h::time_t; + { + pub fn time(__timer: *mut time_t) -> time_t; + } +} +pub mod entenc_c { + pub unsafe fn ec_write_byte( + mut _this: *mut ec_enc, + mut _value: u32, + ) -> i32 { + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage { + return -1; + } + let fresh0 = (*_this).offs; + (*_this).offs = ((*_this).offs).wrapping_add(1); + *((*_this).buf).offset(fresh0 as isize) = _value as u8; + return 0; + } + pub unsafe fn ec_write_byte_at_end( + mut _this: *mut ec_enc, + mut _value: u32, + ) -> i32 { + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage { + return -1; + } + (*_this).end_offs = ((*_this).end_offs).wrapping_add(1); + *((*_this).buf).offset(((*_this).storage).wrapping_sub((*_this).end_offs) as isize) = + _value as u8; + return 0; + } + pub unsafe fn ec_enc_carry_out(mut _this: *mut ec_enc, mut _c: i32) { + if _c as u32 + != ((1 as u32) << 8) + .wrapping_sub(1) + { + let mut carry: i32 = 0; + carry = _c >> 8; + if (*_this).rem >= 0 { + (*_this).error |= ec_write_byte(_this, ((*_this).rem + carry) as u32); + } + if (*_this).ext > 0 { + let mut sym: u32 = 0; + sym = ((1 as u32) << 8) + .wrapping_sub(1) + .wrapping_add(carry as u32) + & ((1 as u32) << 8) + .wrapping_sub(1); + loop { + (*_this).error |= ec_write_byte(_this, sym); + (*_this).ext = ((*_this).ext).wrapping_sub(1); + if !((*_this).ext > 0) { + break; + } + } + } + (*_this).rem = (_c as u32 + & ((1 as u32) << 8) + .wrapping_sub(1)) + as i32; + } else { + (*_this).ext = ((*_this).ext).wrapping_add(1); + }; + } + #[inline] + pub unsafe fn ec_enc_normalize(mut _this: *mut ec_enc) { + while (*_this).rng + <= (1 as u32) << 32 - 1 >> 8 + { + ec_enc_carry_out( + _this, + ((*_this).val >> 32 - 8 - 1) + as i32, + ); + (*_this).val = (*_this).val << 8 + & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + (*_this).rng <<= 8; + (*_this).nbits_total += 8; + } + } + pub unsafe fn ec_enc_init( + mut _this: *mut ec_enc, + mut _buf: *mut u8, + mut _size: u32, + ) { + (*_this).buf = _buf; + (*_this).end_offs = 0; + (*_this).end_window = 0 as ec_window; + (*_this).nend_bits = 0; + (*_this).nbits_total = 32 + 1; + (*_this).offs = 0; + (*_this).rng = (1 as u32) << 32 - 1; + (*_this).rem = -1; + (*_this).val = 0; + (*_this).ext = 0; + (*_this).storage = _size; + (*_this).error = 0; + } + pub unsafe fn ec_encode( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _fh: u32, + mut _ft: u32, + ) { + let mut r: u32 = 0; + r = celt_udiv((*_this).rng, _ft); + if _fl > 0 { + (*_this).val = ((*_this).val as u32) + .wrapping_add(((*_this).rng).wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fl)))) + as u32 as u32; + (*_this).rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fh))) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_encode_bin( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _fh: u32, + mut _bits: u32, + ) { + let mut r: u32 = 0; + r = (*_this).rng >> _bits; + if _fl > 0 { + (*_this).val = ((*_this).val as u32).wrapping_add( + ((*_this).rng) + .wrapping_sub(r.wrapping_mul(((1 as u32) << _bits).wrapping_sub(_fl))), + ) as u32 as u32; + (*_this).rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(((1 as u32) << _bits).wrapping_sub(_fh))) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_bit_logp( + mut _this: *mut ec_enc, + mut _val: i32, + mut _logp: u32, + ) { + let mut r: u32 = 0; + let mut s: u32 = 0; + let mut l: u32 = 0; + r = (*_this).rng; + l = (*_this).val; + s = r >> _logp; + r = (r as u32).wrapping_sub(s) as u32 as u32; + if _val != 0 { + (*_this).val = l.wrapping_add(r); + } + (*_this).rng = if _val != 0 { s } else { r }; + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_done(mut _this: *mut ec_enc) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + let mut msk: u32 = 0; + let mut end: u32 = 0; + let mut l: i32 = 0; + l = 32 + - (::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32); + msk = ((1 as u32) << 32 - 1) + .wrapping_sub(1) + >> l; + end = ((*_this).val).wrapping_add(msk) & !msk; + if end | msk >= ((*_this).val).wrapping_add((*_this).rng) { + l += 1; + msk >>= 1; + end = ((*_this).val).wrapping_add(msk) & !msk; + } + while l > 0 { + ec_enc_carry_out( + _this, + (end >> 32 - 8 - 1) as i32, + ); + end = end << 8 + & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + l -= 8; + } + if (*_this).rem >= 0 || (*_this).ext > 0 { + ec_enc_carry_out(_this, 0); + } + window = (*_this).end_window; + used = (*_this).nend_bits; + while used >= 8 { + (*_this).error |= ec_write_byte_at_end( + _this, + window + & ((1 as u32) << 8) + .wrapping_sub(1), + ); + window >>= 8; + used -= 8; + } + if (*_this).error == 0 { + memset( + ((*_this).buf).offset((*_this).offs as isize) as *mut core::ffi::c_void, + 0, + (((*_this).storage) + .wrapping_sub((*_this).offs) + .wrapping_sub((*_this).end_offs) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + if used > 0 { + if (*_this).end_offs >= (*_this).storage { + (*_this).error = -1; + } else { + l = -l; + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage + && l < used + { + window &= (((1) << l) - 1) as u32; + (*_this).error = -1; + } + let ref mut fresh1 = *((*_this).buf).offset( + ((*_this).storage) + .wrapping_sub((*_this).end_offs) + .wrapping_sub(1) + as isize, + ); + *fresh1 = (*fresh1 as i32 | window as u8 as i32) + as u8; + } + } + } + } + pub unsafe fn ec_enc_icdf( + mut _this: *mut ec_enc, + mut _s: i32, + mut _icdf: *const u8, + mut _ftb: u32, + ) { + let mut r: u32 = 0; + r = (*_this).rng >> _ftb; + if _s > 0 { + (*_this).val = ((*_this).val as u32).wrapping_add(((*_this).rng).wrapping_sub( + r.wrapping_mul(*_icdf.offset((_s - 1) as isize) as u32), + )) as u32 as u32; + (*_this).rng = r.wrapping_mul( + (*_icdf.offset((_s - 1) as isize) as i32 + - *_icdf.offset(_s as isize) as i32) as u32, + ); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(*_icdf.offset(_s as isize) as u32)) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_shrink(mut _this: *mut ec_enc, mut _size: u32) { + memmove( + ((*_this).buf) + .offset(_size as isize) + .offset(-((*_this).end_offs as isize)) as *mut core::ffi::c_void, + ((*_this).buf) + .offset((*_this).storage as isize) + .offset(-((*_this).end_offs as isize)) as *const core::ffi::c_void, + ((*_this).end_offs as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 + * ((*_this).buf) + .offset(_size as isize) + .offset(-((*_this).end_offs as isize)) + .offset_from( + ((*_this).buf) + .offset((*_this).storage as isize) + .offset(-((*_this).end_offs as isize)), + ) as i64) as u64, + ), + ); + (*_this).storage = _size; + } + pub unsafe fn ec_enc_patch_initial_bits( + mut _this: *mut ec_enc, + mut _val: u32, + mut _nbits: u32, + ) { + let mut shift: i32 = 0; + let mut mask: u32 = 0; + shift = (8).wrapping_sub(_nbits) as i32; + mask = ((((1) << _nbits) - 1) << shift) as u32; + if (*_this).offs > 0 { + *((*_this).buf).offset(0 as isize) = + (*((*_this).buf).offset(0 as isize) as u32 & !mask + | _val << shift) as u8; + } else if (*_this).rem >= 0 { + (*_this).rem = ((*_this).rem as u32 & !mask | _val << shift) as i32; + } else if (*_this).rng + <= (1 as u32) << 32 - 1 >> _nbits + { + (*_this).val = (*_this).val + & !(mask << 32 - 8 - 1) + | _val << 32 - 8 - 1 + shift; + } else { + (*_this).error = -1; + }; + } + pub unsafe fn ec_enc_uint(mut _this: *mut ec_enc, mut _fl: u32, mut _ft: u32) { + let mut ft: u32 = 0; + let mut fl: u32 = 0; + let mut ftb: i32 = 0; + _ft = _ft.wrapping_sub(1); + ftb = ::core::mem::size_of::() as u64 as i32 + * 8 + - _ft.leading_zeros() as i32; + if ftb > 8 { + ftb -= 8; + ft = (_ft >> ftb).wrapping_add(1); + fl = _fl >> ftb; + ec_encode( + _this, + fl, + fl.wrapping_add(1), + ft, + ); + ec_enc_bits( + _this, + _fl & ((1) << ftb).wrapping_sub(1 as u32), + ftb as u32, + ); + } else { + ec_encode( + _this, + _fl, + _fl.wrapping_add(1), + _ft.wrapping_add(1), + ); + }; + } + pub unsafe fn ec_enc_bits( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _bits: u32, + ) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + window = (*_this).end_window; + used = (*_this).nend_bits; + if (used as u32).wrapping_add(_bits) + > (::core::mem::size_of::() as u64 as i32 + * 8) as u32 + { + loop { + (*_this).error |= ec_write_byte_at_end( + _this, + window + & ((1 as u32) << 8) + .wrapping_sub(1), + ); + window >>= 8; + used -= 8; + if !(used >= 8) { + break; + } + } + } + window |= _fl << used; + used = (used as u32).wrapping_add(_bits) as i32 as i32; + (*_this).end_window = window; + (*_this).nend_bits = used; + (*_this).nbits_total = ((*_this).nbits_total as u32).wrapping_add(_bits) + as i32 as i32; + } + use super::entcode_h::{celt_udiv, ec_enc, ec_window}; + use crate::externs::{memmove, memset}; +} +pub mod entdec_c { + pub unsafe fn ec_read_byte(mut _this: &mut ec_dec) -> i32 { + return if (*_this).offs < (*_this).storage { + let fresh2 = (*_this).offs; + (*_this).offs = ((*_this).offs).wrapping_add(1); + *((*_this).buf).offset(fresh2 as isize) as i32 + } else { + 0 + }; + } + pub unsafe fn ec_read_byte_from_end(mut _this: &mut ec_dec) -> i32 { + return if (*_this).end_offs < (*_this).storage { + (*_this).end_offs = ((*_this).end_offs).wrapping_add(1); + *((*_this).buf).offset(((*_this).storage).wrapping_sub((*_this).end_offs) as isize) + as i32 + } else { + 0 + }; + } + pub unsafe fn ec_dec_normalize(mut _this: &mut ec_dec) { + while (*_this).rng + <= (1 as u32) << 32 - 1 >> 8 + { + let mut sym: i32 = 0; + (*_this).nbits_total += 8; + (*_this).rng <<= 8; + sym = (*_this).rem; + (*_this).rem = ec_read_byte(_this); + sym = (sym << 8 | (*_this).rem) + >> 8 + - ((32 - 2) % 8 + + 1); + (*_this).val = ((*_this).val << 8).wrapping_add( + ((1 as u32) << 8) + .wrapping_sub(1) + & !sym as u32, + ) & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + } + } + pub unsafe fn ec_dec_init( + mut _this: &mut ec_dec, + mut _buf: *mut u8, + mut _storage: u32, + ) { + (*_this).buf = _buf; + (*_this).storage = _storage; + (*_this).end_offs = 0; + (*_this).end_window = 0 as ec_window; + (*_this).nend_bits = 0; + (*_this).nbits_total = 32 + 1 + - (32 + - ((32 - 2) % 8 + 1)) + / 8 + * 8; + (*_this).offs = 0; + (*_this).rng = (1 as u32) + << (32 - 2) % 8 + 1; + (*_this).rem = ec_read_byte(_this); + (*_this).val = ((*_this).rng) + .wrapping_sub(1) + .wrapping_sub( + ((*_this).rem + >> 8 + - ((32 - 2) % 8 + + 1)) as u32, + ); + (*_this).error = 0; + ec_dec_normalize(_this); + } + pub unsafe fn ec_decode( + mut _this: &mut ec_dec, + mut _ft: u32, + ) -> u32 { + let mut s: u32 = 0; + (*_this).ext = celt_udiv((*_this).rng, _ft); + s = ((*_this).val).wrapping_div((*_this).ext); + return _ft.wrapping_sub( + s.wrapping_add(1) + .wrapping_add( + _ft.wrapping_sub(s.wrapping_add(1)) + & -((_ft < s.wrapping_add(1)) as i32) + as u32, + ), + ); + } + pub unsafe fn ec_decode_bin( + mut _this: &mut ec_dec, + mut _bits: u32, + ) -> u32 { + let mut s: u32 = 0; + (*_this).ext = (*_this).rng >> _bits; + s = ((*_this).val).wrapping_div((*_this).ext); + return ((1 as u32) << _bits).wrapping_sub( + s.wrapping_add(1 as u32).wrapping_add( + ((1 as u32) << _bits).wrapping_sub(s.wrapping_add(1 as u32)) + & -(((1 as u32) << _bits < s.wrapping_add(1 as u32)) + as i32) as u32, + ), + ); + } + pub unsafe fn ec_dec_update( + mut _this: &mut ec_dec, + mut _fl: u32, + mut _fh: u32, + mut _ft: u32, + ) { + let mut s: u32 = 0; + s = ((*_this).ext).wrapping_mul(_ft.wrapping_sub(_fh)); + (*_this).val = ((*_this).val as u32).wrapping_sub(s) as u32 as u32; + (*_this).rng = if _fl > 0 { + ((*_this).ext).wrapping_mul(_fh.wrapping_sub(_fl)) + } else { + ((*_this).rng).wrapping_sub(s) + }; + ec_dec_normalize(_this); + } + pub unsafe fn ec_dec_bit_logp( + mut _this: &mut ec_dec, + mut _logp: u32, + ) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut ret: i32 = 0; + r = (*_this).rng; + d = (*_this).val; + s = r >> _logp; + ret = (d < s) as i32; + if ret == 0 { + (*_this).val = d.wrapping_sub(s); + } + (*_this).rng = if ret != 0 { s } else { r.wrapping_sub(s) }; + ec_dec_normalize(_this); + return ret; + } + pub unsafe fn ec_dec_icdf( + mut _this: &mut ec_dec, + mut _icdf: *const u8, + mut _ftb: u32, + ) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut t: u32 = 0; + let mut ret: i32 = 0; + s = (*_this).rng; + d = (*_this).val; + r = s >> _ftb; + ret = -1; + loop { + t = s; + ret += 1; + s = r.wrapping_mul(*_icdf.offset(ret as isize) as u32); + if !(d < s) { + break; + } + } + (*_this).val = d.wrapping_sub(s); + (*_this).rng = t.wrapping_sub(s); + ec_dec_normalize(_this); + return ret; + } + pub unsafe fn ec_dec_uint(mut _this: &mut ec_dec, mut _ft: u32) -> u32 { + let mut ft: u32 = 0; + let mut s: u32 = 0; + let mut ftb: i32 = 0; + _ft = _ft.wrapping_sub(1); + ftb = ::core::mem::size_of::() as u64 as i32 + * 8 + - _ft.leading_zeros() as i32; + if ftb > 8 { + let mut t: u32 = 0; + ftb -= 8; + ft = (_ft >> ftb).wrapping_add(1); + s = ec_decode(_this, ft); + ec_dec_update( + _this, + s, + s.wrapping_add(1), + ft, + ); + t = s << ftb | ec_dec_bits(_this, ftb as u32); + if t <= _ft { + return t; + } + (*_this).error = 1; + return _ft; + } else { + _ft = _ft.wrapping_add(1); + s = ec_decode(_this, _ft); + ec_dec_update( + _this, + s, + s.wrapping_add(1), + _ft, + ); + return s; + }; + } + pub unsafe fn ec_dec_bits(mut _this: &mut ec_dec, mut _bits: u32) -> u32 { + let mut window: ec_window = 0; + let mut available: i32 = 0; + let mut ret: u32 = 0; + window = (*_this).end_window; + available = (*_this).nend_bits; + if (available as u32) < _bits { + loop { + window |= (ec_read_byte_from_end(_this) as ec_window) << available; + available += 8; + if !(available + <= ::core::mem::size_of::() as u64 as i32 + * 8 + - 8) + { + break; + } + } + } + ret = window & ((1) << _bits).wrapping_sub(1 as u32); + window >>= _bits; + available = (available as u32).wrapping_sub(_bits) as i32 as i32; + (*_this).end_window = window; + (*_this).nend_bits = available; + (*_this).nbits_total = ((*_this).nbits_total as u32).wrapping_add(_bits) + as i32 as i32; + return ret; + } + use super::entcode_h::{celt_udiv, ec_dec, ec_window}; +} +pub mod entcode_c { + pub unsafe fn ec_tell_frac(mut _this: *mut ec_ctx) -> u32 { + pub static mut correction: [u32; 8] = [ + 35733, + 38967, + 42495, + 46340, + 50535, + 55109, + 60097, + 65535, + ]; + let mut nbits: u32 = 0; + let mut r: u32 = 0; + let mut l: i32 = 0; + let mut b: u32 = 0; + nbits = ((*_this).nbits_total << 3) as u32; + l = ::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32; + r = (*_this).rng >> l - 16; + b = (r >> 12).wrapping_sub(8); + b = b.wrapping_add((r > correction[b as usize]) as i32 as u32); + l = ((l << 3) as u32).wrapping_add(b) as i32; + return nbits.wrapping_sub(l as u32); + } + use super::entcode_h::ec_ctx; +} +pub use self::entcode_c::ec_tell_frac; +pub use self::entcode_h::{celt_udiv, ec_ctx, ec_dec, ec_enc, ec_range_bytes, ec_tell, ec_window}; +pub use self::entdec_c::{ + ec_dec_bit_logp, ec_dec_bits, ec_dec_icdf, ec_dec_init, ec_dec_normalize, ec_dec_uint, + ec_dec_update, ec_decode, ec_decode_bin, ec_read_byte, ec_read_byte_from_end, +}; +pub use self::entenc_c::{ + ec_enc_bit_logp, ec_enc_bits, ec_enc_carry_out, ec_enc_done, ec_enc_icdf, ec_enc_init, + ec_enc_normalize, ec_enc_patch_initial_bits, ec_enc_shrink, ec_enc_uint, ec_encode, + ec_encode_bin, ec_write_byte, ec_write_byte_at_end, +}; +use self::mathcalls_h::{ldexp, log}; +pub use self::stddef_h::size_t; + +use self::stdio_h::{fprintf, stderr}; +pub use self::stdlib_h::{atoi, free, getenv, malloc, rand, srand, strtol}; +pub use self::struct_FILE_h::{_IO_codecvt, _IO_lock_t, _IO_marker, _IO_wide_data, _IO_FILE}; +use self::time_h::time; +pub use self::time_t_h::time_t; + +pub use self::FILE_h::FILE; +use crate::externs::{memmove, memset}; +unsafe fn main_0(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 { + let mut enc: ec_enc = ec_enc { + buf: 0 as *mut u8, + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut dec: ec_dec = ec_enc { + buf: 0 as *mut u8, + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut nbits: i64 = 0; + let mut nbits2: i64 = 0; + let mut entropy: f64 = 0.; + let mut ft: i32 = 0; + let mut ftb: i32 = 0; + let mut sz: i32 = 0; + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut sym: u32 = 0; + let mut seed: u32 = 0; + let mut ptr: *mut u8 = 0 as *mut u8; + let mut env_seed: *const i8 = 0 as *const i8; + ret = 0; + entropy = 0 as f64; + if _argc > 2 { + fprintf( + stderr(), + b"Usage: %s []\n\0" as *const u8 as *const i8, + *_argv.offset(0 as isize), + ); + return 1; + } + env_seed = getenv(b"SEED\0" as *const u8 as *const i8); + if _argc > 1 { + seed = atoi(*_argv.offset(1 as isize)) as u32; + } else if !env_seed.is_null() { + seed = atoi(env_seed) as u32; + } else { + seed = time(0 as *mut time_t) as u32; + } + ptr = malloc(10000000) as *mut u8; + ec_enc_init(&mut enc, ptr, 10000000); + ft = 2; + while ft < 1024 { + i = 0; + while i < ft { + entropy += log(ft as f64) * 1.4426950408889634074f64; + ec_enc_uint(&mut enc, i as u32, ft as u32); + i += 1; + } + ft += 1; + } + ftb = 1; + while ftb < 16 { + i = 0; + while i < (1) << ftb { + entropy += ftb as f64; + nbits = ec_tell(&mut enc) as i64; + ec_enc_bits(&mut enc, i as u32, ftb as u32); + nbits2 = ec_tell(&mut enc) as i64; + if nbits2 - nbits != ftb as i64 { + fprintf( + stderr(), + b"Used %li bits to encode %i bits directly.\n\0" as *const u8 + as *const i8, + nbits2 - nbits, + ftb, + ); + ret = -1; + } + i += 1; + } + ftb += 1; + } + nbits = ec_tell_frac(&mut enc) as i64; + ec_enc_done(&mut enc); + fprintf( + stderr(), + b"Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n\0" as *const u8 + as *const i8, + entropy, + ldexp(nbits as f64, -(3)), + 100 as f64 + * (nbits as f64 - ldexp(entropy, 3)) + / nbits as f64, + ); + fprintf( + stderr(), + b"Packed to %li bytes.\n\0" as *const u8 as *const i8, + ec_range_bytes(&mut enc) as i64, + ); + ec_dec_init(dec, ptr, 10000000); + ft = 2; + while ft < 1024 { + i = 0; + while i < ft { + sym = ec_dec_uint(dec, ft as u32); + if sym != i as u32 { + fprintf( + stderr(), + b"Decoded %i instead of %i with ft of %i.\n\0" as *const u8 + as *const i8, + sym, + i, + ft, + ); + ret = -1; + } + i += 1; + } + ft += 1; + } + ftb = 1; + while ftb < 16 { + i = 0; + while i < (1) << ftb { + sym = ec_dec_bits(dec, ftb as u32); + if sym != i as u32 { + fprintf( + stderr(), + b"Decoded %i instead of %i with ftb of %i.\n\0" as *const u8 + as *const i8, + sym, + i, + ftb, + ); + ret = -1; + } + i += 1; + } + ftb += 1; + } + nbits2 = ec_tell_frac(dec) as i64; + if nbits != nbits2 { + fprintf( + stderr(), + b"Reported number of bits used was %0.2lf, should be %0.2lf.\n\0" as *const u8 + as *const i8, + ldexp(nbits2 as f64, -(3)), + ldexp(nbits as f64, -(3)), + ); + ret = -1; + } + ec_enc_init(&mut enc, ptr, 2); + ec_enc_bits( + &mut enc, + 0x55, + 7, + ); + ec_enc_uint(&mut enc, 1, 2); + ec_enc_uint(&mut enc, 1, 3); + ec_enc_uint(&mut enc, 1, 4); + ec_enc_uint(&mut enc, 1, 5); + ec_enc_uint(&mut enc, 2, 6); + ec_enc_uint(&mut enc, 6, 7); + ec_enc_done(&mut enc); + ec_dec_init(dec, ptr, 2); + if enc.error == 0 + || ec_dec_bits(dec, 7) + != 0x5 + || ec_dec_uint(dec, 2) != 1 + || ec_dec_uint(dec, 3) != 1 + || ec_dec_uint(dec, 4) != 1 + || ec_dec_uint(dec, 5) != 1 + || ec_dec_uint(dec, 6) != 2 + || ec_dec_uint(dec, 7) != 6 + { + fprintf( + stderr(), + b"Encoder bust overwrote range coder data with raw bits.\n\0" as *const u8 + as *const i8, + ); + ret = -1; + } + srand(seed); + fprintf( + stderr(), + b"Testing random streams... Random seed: %u (%.4X)\n\0" as *const u8 as *const i8, + seed, + rand() % 65536, + ); + i = 0; + while i < 409600 { + let mut data: *mut u32 = 0 as *mut u32; + let mut tell: *mut u32 = 0 as *mut u32; + let mut tell_bits: u32 = 0; + let mut j: i32 = 0; + let mut zeros: i32 = 0; + ft = (rand() as u32) + .wrapping_div( + ((2147483647 + >> (rand() as u32).wrapping_rem(11 as u32)) + as u32) + .wrapping_add(1 as u32), + ) + .wrapping_add(10) as i32; + sz = + (rand() as u32).wrapping_div( + ((2147483647 + >> (rand() as u32).wrapping_rem(9 as u32)) + as u32) + .wrapping_add(1 as u32), + ) as i32; + data = malloc( + (sz as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as *mut u32; + tell = malloc( + ((sz + 1) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as *mut u32; + ec_enc_init(&mut enc, ptr, 10000); + zeros = (rand() % 13 == 0) as i32; + *tell.offset(0 as isize) = ec_tell_frac(&mut enc); + j = 0; + while j < sz { + if zeros != 0 { + *data.offset(j as isize) = 0; + } else { + *data.offset(j as isize) = (rand() % ft) as u32; + } + ec_enc_uint(&mut enc, *data.offset(j as isize), ft as u32); + *tell.offset((j + 1) as isize) = ec_tell_frac(&mut enc); + j += 1; + } + if rand() % 2 == 0 { + while ec_tell(&mut enc) % 8 != 0 { + ec_enc_uint( + &mut enc, + (rand() % 2) as u32, + 2, + ); + } + } + tell_bits = ec_tell(&mut enc) as u32; + ec_enc_done(&mut enc); + if tell_bits != ec_tell(&mut enc) as u32 { + fprintf( + stderr(), + b"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n\0" + as *const u8 as *const i8, + ec_tell(&mut enc), + tell_bits, + seed, + ); + ret = -1; + } + if tell_bits + .wrapping_add(7) + .wrapping_div(8) + < ec_range_bytes(&mut enc) + { + fprintf( + stderr(), + b"ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n\0" as *const u8 + as *const i8, + ec_range_bytes(&mut enc), + tell_bits + .wrapping_add(7) + .wrapping_div(8), + seed, + ); + ret = -1; + } + ec_dec_init(dec, ptr, 10000); + if ec_tell_frac(dec) != *tell.offset(0 as isize) { + fprintf( + stderr(), + b"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n\0" + as *const u8 as *const i8, + 0, + ec_tell_frac(dec), + *tell.offset(0 as isize), + seed, + ); + } + j = 0; + while j < sz { + sym = ec_dec_uint(dec, ft as u32); + if sym != *data.offset(j as isize) { + fprintf( + stderr(), + b"Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n\0" + as *const u8 as *const i8, + sym, + *data.offset(j as isize), + ft, + j, + sz, + seed, + ); + ret = -1; + } + if ec_tell_frac(dec) != *tell.offset((j + 1) as isize) { + fprintf( + stderr(), + b"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n\0" + as *const u8 as *const i8, + j + 1, + ec_tell_frac(dec), + *tell.offset((j + 1) as isize), + seed, + ); + } + j += 1; + } + free(tell as *mut core::ffi::c_void); + free(data as *mut core::ffi::c_void); + i += 1; + } + i = 0; + while i < 409600 { + let mut logp1: *mut u32 = 0 as *mut u32; + let mut data_0: *mut u32 = 0 as *mut u32; + let mut tell_0: *mut u32 = 0 as *mut u32; + let mut enc_method: *mut u32 = 0 as *mut u32; + let mut j_0: i32 = 0; + sz = + (rand() as u32).wrapping_div( + ((2147483647 + >> (rand() as u32).wrapping_rem(9 as u32)) + as u32) + .wrapping_add(1 as u32), + ) as i32; + logp1 = malloc( + (sz as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as *mut u32; + data_0 = malloc( + (sz as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as *mut u32; + tell_0 = malloc( + ((sz + 1) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as *mut u32; + enc_method = malloc( + (sz as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ) as *mut u32; + ec_enc_init(&mut enc, ptr, 10000); + *tell_0.offset(0 as isize) = ec_tell_frac(&mut enc); + j_0 = 0; + while j_0 < sz { + *data_0.offset(j_0 as isize) = (rand() + / ((2147483647 >> 1) + 1)) + as u32; + *logp1.offset(j_0 as isize) = + (rand() % 15 + 1) as u32; + *enc_method.offset(j_0 as isize) = (rand() + / ((2147483647 >> 2) + 1)) + as u32; + match *enc_method.offset(j_0 as isize) { + 0 => { + ec_encode( + &mut enc, + (if *data_0.offset(j_0 as isize) != 0 { + ((1) << *logp1.offset(j_0 as isize)) - 1 + } else { + 0 + }) as u32, + (((1) << *logp1.offset(j_0 as isize)) + - (if *data_0.offset(j_0 as isize) != 0 { + 0 + } else { + 1 + })) as u32, + ((1) << *logp1.offset(j_0 as isize)) as u32, + ); + } + 1 => { + ec_encode_bin( + &mut enc, + (if *data_0.offset(j_0 as isize) != 0 { + ((1) << *logp1.offset(j_0 as isize)) - 1 + } else { + 0 + }) as u32, + (((1) << *logp1.offset(j_0 as isize)) + - (if *data_0.offset(j_0 as isize) != 0 { + 0 + } else { + 1 + })) as u32, + *logp1.offset(j_0 as isize), + ); + } + 2 => { + ec_enc_bit_logp( + &mut enc, + *data_0.offset(j_0 as isize) as i32, + *logp1.offset(j_0 as isize), + ); + } + 3 => { + let mut icdf: [u8; 2] = [0; 2]; + icdf[0 as usize] = 1; + icdf[1 as usize] = 0; + ec_enc_icdf( + &mut enc, + *data_0.offset(j_0 as isize) as i32, + icdf.as_mut_ptr(), + *logp1.offset(j_0 as isize), + ); + } + _ => {} + } + *tell_0.offset((j_0 + 1) as isize) = ec_tell_frac(&mut enc); + j_0 += 1; + } + ec_enc_done(&mut enc); + if (ec_tell(&mut enc) as u32) + .wrapping_add(7 as u32) + .wrapping_div(8 as u32) + < ec_range_bytes(&mut enc) + { + fprintf( + stderr(), + b"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n\0" as *const u8 + as *const i8, + ec_range_bytes(&mut enc), + (ec_tell(&mut enc) + 7) / 8, + seed, + ); + ret = -1; + } + ec_dec_init(dec, ptr, 10000); + if ec_tell_frac(dec) != *tell_0.offset(0 as isize) { + fprintf( + stderr(), + b"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n\0" + as *const u8 as *const i8, + 0, + ec_tell_frac(dec), + *tell_0.offset(0 as isize), + seed, + ); + } + j_0 = 0; + while j_0 < sz { + let mut fs: i32 = 0; + let mut dec_method: i32 = 0; + dec_method = + rand() / ((2147483647 >> 2) + 1); + match dec_method { + 0 => { + fs = ec_decode( + dec, + ((1) << *logp1.offset(j_0 as isize)) as u32, + ) as i32; + sym = (fs + >= ((1) << *logp1.offset(j_0 as isize)) - 1) + as i32 as u32; + ec_dec_update( + dec, + (if sym != 0 { + ((1) << *logp1.offset(j_0 as isize)) - 1 + } else { + 0 + }) as u32, + (((1) << *logp1.offset(j_0 as isize)) + - (if sym != 0 { + 0 + } else { + 1 + })) as u32, + ((1) << *logp1.offset(j_0 as isize)) as u32, + ); + } + 1 => { + fs = ec_decode_bin(dec, *logp1.offset(j_0 as isize)) as i32; + sym = (fs + >= ((1) << *logp1.offset(j_0 as isize)) - 1) + as i32 as u32; + ec_dec_update( + dec, + (if sym != 0 { + ((1) << *logp1.offset(j_0 as isize)) - 1 + } else { + 0 + }) as u32, + (((1) << *logp1.offset(j_0 as isize)) + - (if sym != 0 { + 0 + } else { + 1 + })) as u32, + ((1) << *logp1.offset(j_0 as isize)) as u32, + ); + } + 2 => { + sym = ec_dec_bit_logp(dec, *logp1.offset(j_0 as isize)) as u32; + } + 3 => { + let mut icdf_0: [u8; 2] = [0; 2]; + icdf_0[0 as usize] = 1; + icdf_0[1 as usize] = 0; + sym = ec_dec_icdf(dec, icdf_0.as_mut_ptr(), *logp1.offset(j_0 as isize)) + as u32; + } + _ => {} + } + if sym != *data_0.offset(j_0 as isize) { + fprintf( + stderr(), + b"Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n\0" + as *const u8 as *const i8, + sym, + *data_0.offset(j_0 as isize), + *logp1.offset(j_0 as isize), + j_0, + sz, + seed, + ); + fprintf( + stderr(), + b"Encoding method: %i, decoding method: %i\n\0" as *const u8 + as *const i8, + *enc_method.offset(j_0 as isize), + dec_method, + ); + ret = -1; + } + if ec_tell_frac(dec) != *tell_0.offset((j_0 + 1) as isize) { + fprintf( + stderr(), + b"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n\0" + as *const u8 as *const i8, + j_0 + 1, + ec_tell_frac(dec), + *tell_0.offset((j_0 + 1) as isize), + seed, + ); + } + j_0 += 1; + } + free(enc_method as *mut core::ffi::c_void); + free(tell_0 as *mut core::ffi::c_void); + free(data_0 as *mut core::ffi::c_void); + free(logp1 as *mut core::ffi::c_void); + i += 1; + } + ec_enc_init(&mut enc, ptr, 10000); + ec_enc_bit_logp(&mut enc, 0, 1); + ec_enc_bit_logp(&mut enc, 0, 1); + ec_enc_bit_logp(&mut enc, 0, 1); + ec_enc_bit_logp(&mut enc, 0, 1); + ec_enc_bit_logp(&mut enc, 0, 2); + ec_enc_patch_initial_bits( + &mut enc, + 3, + 2, + ); + if enc.error != 0 { + fprintf( + stderr(), + b"patch_initial_bits failed\0" as *const u8 as *const i8, + ); + ret = -1; + } + ec_enc_patch_initial_bits( + &mut enc, + 0, + 5, + ); + if enc.error == 0 { + fprintf( + stderr(), + b"patch_initial_bits didn't fail when it should have\0" as *const u8 + as *const i8, + ); + ret = -1; + } + ec_enc_done(&mut enc); + if ec_range_bytes(&mut enc) != 1 + || *ptr.offset(0 as isize) as i32 != 192 + { + fprintf( + stderr(), + b"Got %d when expecting 192 for patch_initial_bits\0" as *const u8 + as *const i8, + *ptr.offset(0 as isize) as i32, + ); + ret = -1; + } + ec_enc_init(&mut enc, ptr, 10000); + ec_enc_bit_logp(&mut enc, 0, 1); + ec_enc_bit_logp(&mut enc, 0, 1); + ec_enc_bit_logp(&mut enc, 1, 6); + ec_enc_bit_logp(&mut enc, 0, 2); + ec_enc_patch_initial_bits( + &mut enc, + 0, + 2, + ); + if enc.error != 0 { + fprintf( + stderr(), + b"patch_initial_bits failed\0" as *const u8 as *const i8, + ); + ret = -1; + } + ec_enc_done(&mut enc); + if ec_range_bytes(&mut enc) != 2 + || *ptr.offset(0 as isize) as i32 != 63 + { + fprintf( + stderr(), + b"Got %d when expecting 63 for patch_initial_bits\0" as *const u8 + as *const i8, + *ptr.offset(0 as isize) as i32, + ); + ret = -1; + } + ec_enc_init(&mut enc, ptr, 2); + ec_enc_bit_logp(&mut enc, 0, 2); + i = 0; + while i < 48 { + ec_enc_bits( + &mut enc, + 0, + 1, + ); + i += 1; + } + ec_enc_done(&mut enc); + if enc.error == 0 { + fprintf( + stderr(), + b"Raw bits overfill didn't fail when it should have\0" as *const u8 + as *const i8, + ); + ret = -1; + } + ec_enc_init(&mut enc, ptr, 2); + i = 0; + while i < 17 { + ec_enc_bits( + &mut enc, + 0, + 1, + ); + i += 1; + } + ec_enc_done(&mut enc); + if enc.error == 0 { + fprintf( + stderr(), + b"17 raw bits encoded in two bytes\0" as *const u8 as *const i8, + ); + ret = -1; + } + free(ptr as *mut core::ffi::c_void); + return ret; +} +pub fn main() { + let mut args: Vec<*mut i8> = Vec::new(); + for arg in ::std::env::args() { + args.push( + (::std::ffi::CString::new(arg)) + .expect("Failed to convert argument into CString.") + .into_raw(), + ); + } + args.push(::core::ptr::null_mut()); + unsafe { + ::std::process::exit(main_0( + (args.len() - 1) as i32, + args.as_mut_ptr() as *mut *mut i8, + ) as i32) + } +} diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_laplace.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_laplace.rs new file mode 100644 index 00000000..addd16f8 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_laplace.rs @@ -0,0 +1,931 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod entcode_h { + pub type ec_window = u32; + #[derive(Copy, Clone)] + #[repr(C)] + pub struct ec_ctx { + pub buf: *mut u8, + pub storage: u32, + pub end_offs: u32, + pub end_window: ec_window, + pub nend_bits: i32, + pub nbits_total: i32, + pub offs: u32, + pub rng: u32, + pub val: u32, + pub ext: u32, + pub rem: i32, + pub error: i32, + } + pub type ec_enc = ec_ctx; + pub type ec_dec = ec_ctx; + #[inline] + pub unsafe fn ec_range_bytes(mut _this: *mut ec_ctx) -> u32 { + return (*_this).offs; + } + #[inline] + pub unsafe fn ec_get_buffer(mut _this: *mut ec_ctx) -> *mut u8 { + return (*_this).buf; + } + #[inline] + pub unsafe fn celt_udiv(mut n: u32, mut d: u32) -> u32 { + return n.wrapping_div(d); + } +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + } +} +pub mod stdlib_h { + { + pub fn rand() -> i32; + pub fn malloc(_: u64) -> *mut core::ffi::c_void; + pub fn free(_: *mut core::ffi::c_void); + } +} +pub mod entenc_c { + pub unsafe fn ec_enc_carry_out(mut _this: *mut ec_enc, mut _c: i32) { + if _c as u32 + != ((1 as u32) << 8) + .wrapping_sub(1) + { + let mut carry: i32 = 0; + carry = _c >> 8; + if (*_this).rem >= 0 { + (*_this).error |= ec_write_byte(_this, ((*_this).rem + carry) as u32); + } + if (*_this).ext > 0 { + let mut sym: u32 = 0; + sym = ((1 as u32) << 8) + .wrapping_sub(1) + .wrapping_add(carry as u32) + & ((1 as u32) << 8) + .wrapping_sub(1); + loop { + (*_this).error |= ec_write_byte(_this, sym); + (*_this).ext = ((*_this).ext).wrapping_sub(1); + if !((*_this).ext > 0) { + break; + } + } + } + (*_this).rem = (_c as u32 + & ((1 as u32) << 8) + .wrapping_sub(1)) + as i32; + } else { + (*_this).ext = ((*_this).ext).wrapping_add(1); + }; + } + pub unsafe fn ec_write_byte( + mut _this: *mut ec_enc, + mut _value: u32, + ) -> i32 { + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage { + return -1; + } + let fresh0 = (*_this).offs; + (*_this).offs = ((*_this).offs).wrapping_add(1); + *((*_this).buf).offset(fresh0 as isize) = _value as u8; + return 0; + } + pub unsafe fn ec_write_byte_at_end( + mut _this: *mut ec_enc, + mut _value: u32, + ) -> i32 { + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage { + return -1; + } + (*_this).end_offs = ((*_this).end_offs).wrapping_add(1); + *((*_this).buf).offset(((*_this).storage).wrapping_sub((*_this).end_offs) as isize) = + _value as u8; + return 0; + } + #[inline] + pub unsafe fn ec_enc_normalize(mut _this: *mut ec_enc) { + while (*_this).rng + <= (1 as u32) << 32 - 1 >> 8 + { + ec_enc_carry_out( + _this, + ((*_this).val >> 32 - 8 - 1) + as i32, + ); + (*_this).val = (*_this).val << 8 + & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + (*_this).rng <<= 8; + (*_this).nbits_total += 8; + } + } + pub unsafe fn ec_enc_init( + mut _this: *mut ec_enc, + mut _buf: *mut u8, + mut _size: u32, + ) { + (*_this).buf = _buf; + (*_this).end_offs = 0; + (*_this).end_window = 0 as ec_window; + (*_this).nend_bits = 0; + (*_this).nbits_total = 32 + 1; + (*_this).offs = 0; + (*_this).rng = (1 as u32) << 32 - 1; + (*_this).rem = -1; + (*_this).val = 0; + (*_this).ext = 0; + (*_this).storage = _size; + (*_this).error = 0; + } + pub unsafe fn ec_encode( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _fh: u32, + mut _ft: u32, + ) { + let mut r: u32 = 0; + r = celt_udiv((*_this).rng, _ft); + if _fl > 0 { + (*_this).val = ((*_this).val as u32) + .wrapping_add(((*_this).rng).wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fl)))) + as u32 as u32; + (*_this).rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(_ft.wrapping_sub(_fh))) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_encode_bin( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _fh: u32, + mut _bits: u32, + ) { + let mut r: u32 = 0; + r = (*_this).rng >> _bits; + if _fl > 0 { + (*_this).val = ((*_this).val as u32).wrapping_add( + ((*_this).rng) + .wrapping_sub(r.wrapping_mul(((1 as u32) << _bits).wrapping_sub(_fl))), + ) as u32 as u32; + (*_this).rng = r.wrapping_mul(_fh.wrapping_sub(_fl)); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(((1 as u32) << _bits).wrapping_sub(_fh))) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_bit_logp( + mut _this: *mut ec_enc, + mut _val: i32, + mut _logp: u32, + ) { + let mut r: u32 = 0; + let mut s: u32 = 0; + let mut l: u32 = 0; + r = (*_this).rng; + l = (*_this).val; + s = r >> _logp; + r = (r as u32).wrapping_sub(s) as u32 as u32; + if _val != 0 { + (*_this).val = l.wrapping_add(r); + } + (*_this).rng = if _val != 0 { s } else { r }; + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_icdf( + mut _this: *mut ec_enc, + mut _s: i32, + mut _icdf: *const u8, + mut _ftb: u32, + ) { + let mut r: u32 = 0; + r = (*_this).rng >> _ftb; + if _s > 0 { + (*_this).val = ((*_this).val as u32).wrapping_add(((*_this).rng).wrapping_sub( + r.wrapping_mul(*_icdf.offset((_s - 1) as isize) as u32), + )) as u32 as u32; + (*_this).rng = r.wrapping_mul( + (*_icdf.offset((_s - 1) as isize) as i32 + - *_icdf.offset(_s as isize) as i32) as u32, + ); + } else { + (*_this).rng = ((*_this).rng as u32) + .wrapping_sub(r.wrapping_mul(*_icdf.offset(_s as isize) as u32)) + as u32 as u32; + } + ec_enc_normalize(_this); + } + pub unsafe fn ec_enc_uint(mut _this: *mut ec_enc, mut _fl: u32, mut _ft: u32) { + let mut ft: u32 = 0; + let mut fl: u32 = 0; + let mut ftb: i32 = 0; + _ft = _ft.wrapping_sub(1); + ftb = ::core::mem::size_of::() as u64 as i32 + * 8 + - _ft.leading_zeros() as i32; + if ftb > 8 { + ftb -= 8; + ft = (_ft >> ftb).wrapping_add(1); + fl = _fl >> ftb; + ec_encode( + _this, + fl, + fl.wrapping_add(1), + ft, + ); + ec_enc_bits( + _this, + _fl & ((1) << ftb).wrapping_sub(1 as u32), + ftb as u32, + ); + } else { + ec_encode( + _this, + _fl, + _fl.wrapping_add(1), + _ft.wrapping_add(1), + ); + }; + } + pub unsafe fn ec_enc_bits( + mut _this: *mut ec_enc, + mut _fl: u32, + mut _bits: u32, + ) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + window = (*_this).end_window; + used = (*_this).nend_bits; + if (used as u32).wrapping_add(_bits) + > (::core::mem::size_of::() as u64 as i32 + * 8) as u32 + { + loop { + (*_this).error |= ec_write_byte_at_end( + _this, + window + & ((1 as u32) << 8) + .wrapping_sub(1), + ); + window >>= 8; + used -= 8; + if !(used >= 8) { + break; + } + } + } + window |= _fl << used; + used = (used as u32).wrapping_add(_bits) as i32 as i32; + (*_this).end_window = window; + (*_this).nend_bits = used; + (*_this).nbits_total = ((*_this).nbits_total as u32).wrapping_add(_bits) + as i32 as i32; + } + pub unsafe fn ec_enc_patch_initial_bits( + mut _this: *mut ec_enc, + mut _val: u32, + mut _nbits: u32, + ) { + let mut shift: i32 = 0; + let mut mask: u32 = 0; + shift = (8).wrapping_sub(_nbits) as i32; + mask = ((((1) << _nbits) - 1) << shift) as u32; + if (*_this).offs > 0 { + *((*_this).buf).offset(0 as isize) = + (*((*_this).buf).offset(0 as isize) as u32 & !mask + | _val << shift) as u8; + } else if (*_this).rem >= 0 { + (*_this).rem = ((*_this).rem as u32 & !mask | _val << shift) as i32; + } else if (*_this).rng + <= (1 as u32) << 32 - 1 >> _nbits + { + (*_this).val = (*_this).val + & !(mask << 32 - 8 - 1) + | _val << 32 - 8 - 1 + shift; + } else { + (*_this).error = -1; + }; + } + pub unsafe fn ec_enc_shrink(mut _this: *mut ec_enc, mut _size: u32) { + memmove( + ((*_this).buf) + .offset(_size as isize) + .offset(-((*_this).end_offs as isize)) as *mut core::ffi::c_void, + ((*_this).buf) + .offset((*_this).storage as isize) + .offset(-((*_this).end_offs as isize)) as *const core::ffi::c_void, + ((*_this).end_offs as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 + * ((*_this).buf) + .offset(_size as isize) + .offset(-((*_this).end_offs as isize)) + .offset_from( + ((*_this).buf) + .offset((*_this).storage as isize) + .offset(-((*_this).end_offs as isize)), + ) as i64) as u64, + ), + ); + (*_this).storage = _size; + } + pub unsafe fn ec_enc_done(mut _this: *mut ec_enc) { + let mut window: ec_window = 0; + let mut used: i32 = 0; + let mut msk: u32 = 0; + let mut end: u32 = 0; + let mut l: i32 = 0; + l = 32 + - (::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32); + msk = ((1 as u32) << 32 - 1) + .wrapping_sub(1) + >> l; + end = ((*_this).val).wrapping_add(msk) & !msk; + if end | msk >= ((*_this).val).wrapping_add((*_this).rng) { + l += 1; + msk >>= 1; + end = ((*_this).val).wrapping_add(msk) & !msk; + } + while l > 0 { + ec_enc_carry_out( + _this, + (end >> 32 - 8 - 1) as i32, + ); + end = end << 8 + & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + l -= 8; + } + if (*_this).rem >= 0 || (*_this).ext > 0 { + ec_enc_carry_out(_this, 0); + } + window = (*_this).end_window; + used = (*_this).nend_bits; + while used >= 8 { + (*_this).error |= ec_write_byte_at_end( + _this, + window + & ((1 as u32) << 8) + .wrapping_sub(1), + ); + window >>= 8; + used -= 8; + } + if (*_this).error == 0 { + memset( + ((*_this).buf).offset((*_this).offs as isize) as *mut core::ffi::c_void, + 0, + (((*_this).storage) + .wrapping_sub((*_this).offs) + .wrapping_sub((*_this).end_offs) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + if used > 0 { + if (*_this).end_offs >= (*_this).storage { + (*_this).error = -1; + } else { + l = -l; + if ((*_this).offs).wrapping_add((*_this).end_offs) >= (*_this).storage + && l < used + { + window &= (((1) << l) - 1) as u32; + (*_this).error = -1; + } + let ref mut fresh1 = *((*_this).buf).offset( + ((*_this).storage) + .wrapping_sub((*_this).end_offs) + .wrapping_sub(1) + as isize, + ); + *fresh1 = (*fresh1 as i32 | window as u8 as i32) + as u8; + } + } + } + } + use super::entcode_h::{celt_udiv, ec_enc, ec_window}; + use crate::externs::{memmove, memset}; +} +pub mod entdec_c { + pub unsafe fn ec_read_byte(mut _this: &mut ec_dec) -> i32 { + return if (*_this).offs < (*_this).storage { + let fresh2 = (*_this).offs; + (*_this).offs = ((*_this).offs).wrapping_add(1); + *((*_this).buf).offset(fresh2 as isize) as i32 + } else { + 0 + }; + } + pub unsafe fn ec_read_byte_from_end(mut _this: &mut ec_dec) -> i32 { + return if (*_this).end_offs < (*_this).storage { + (*_this).end_offs = ((*_this).end_offs).wrapping_add(1); + *((*_this).buf).offset(((*_this).storage).wrapping_sub((*_this).end_offs) as isize) + as i32 + } else { + 0 + }; + } + pub unsafe fn ec_dec_normalize(mut _this: &mut ec_dec) { + while (*_this).rng + <= (1 as u32) << 32 - 1 >> 8 + { + let mut sym: i32 = 0; + (*_this).nbits_total += 8; + (*_this).rng <<= 8; + sym = (*_this).rem; + (*_this).rem = ec_read_byte(_this); + sym = (sym << 8 | (*_this).rem) + >> 8 + - ((32 - 2) % 8 + + 1); + (*_this).val = ((*_this).val << 8).wrapping_add( + ((1 as u32) << 8) + .wrapping_sub(1) + & !sym as u32, + ) & ((1 as u32) << 32 - 1) + .wrapping_sub(1); + } + } + pub unsafe fn ec_dec_init( + mut _this: &mut ec_dec, + mut _buf: *mut u8, + mut _storage: u32, + ) { + (*_this).buf = _buf; + (*_this).storage = _storage; + (*_this).end_offs = 0; + (*_this).end_window = 0 as ec_window; + (*_this).nend_bits = 0; + (*_this).nbits_total = 32 + 1 + - (32 + - ((32 - 2) % 8 + 1)) + / 8 + * 8; + (*_this).offs = 0; + (*_this).rng = (1 as u32) + << (32 - 2) % 8 + 1; + (*_this).rem = ec_read_byte(_this); + (*_this).val = ((*_this).rng) + .wrapping_sub(1) + .wrapping_sub( + ((*_this).rem + >> 8 + - ((32 - 2) % 8 + + 1)) as u32, + ); + (*_this).error = 0; + ec_dec_normalize(_this); + } + pub unsafe fn ec_decode( + mut _this: &mut ec_dec, + mut _ft: u32, + ) -> u32 { + let mut s: u32 = 0; + (*_this).ext = celt_udiv((*_this).rng, _ft); + s = ((*_this).val).wrapping_div((*_this).ext); + return _ft.wrapping_sub( + s.wrapping_add(1) + .wrapping_add( + _ft.wrapping_sub(s.wrapping_add(1)) + & -((_ft < s.wrapping_add(1)) as i32) + as u32, + ), + ); + } + pub unsafe fn ec_decode_bin( + mut _this: &mut ec_dec, + mut _bits: u32, + ) -> u32 { + let mut s: u32 = 0; + (*_this).ext = (*_this).rng >> _bits; + s = ((*_this).val).wrapping_div((*_this).ext); + return ((1 as u32) << _bits).wrapping_sub( + s.wrapping_add(1 as u32).wrapping_add( + ((1 as u32) << _bits).wrapping_sub(s.wrapping_add(1 as u32)) + & -(((1 as u32) << _bits < s.wrapping_add(1 as u32)) + as i32) as u32, + ), + ); + } + pub unsafe fn ec_dec_update( + mut _this: &mut ec_dec, + mut _fl: u32, + mut _fh: u32, + mut _ft: u32, + ) { + let mut s: u32 = 0; + s = ((*_this).ext).wrapping_mul(_ft.wrapping_sub(_fh)); + (*_this).val = ((*_this).val as u32).wrapping_sub(s) as u32 as u32; + (*_this).rng = if _fl > 0 { + ((*_this).ext).wrapping_mul(_fh.wrapping_sub(_fl)) + } else { + ((*_this).rng).wrapping_sub(s) + }; + ec_dec_normalize(_this); + } + pub unsafe fn ec_dec_bit_logp( + mut _this: &mut ec_dec, + mut _logp: u32, + ) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut ret: i32 = 0; + r = (*_this).rng; + d = (*_this).val; + s = r >> _logp; + ret = (d < s) as i32; + if ret == 0 { + (*_this).val = d.wrapping_sub(s); + } + (*_this).rng = if ret != 0 { s } else { r.wrapping_sub(s) }; + ec_dec_normalize(_this); + return ret; + } + pub unsafe fn ec_dec_icdf( + mut _this: &mut ec_dec, + mut _icdf: *const u8, + mut _ftb: u32, + ) -> i32 { + let mut r: u32 = 0; + let mut d: u32 = 0; + let mut s: u32 = 0; + let mut t: u32 = 0; + let mut ret: i32 = 0; + s = (*_this).rng; + d = (*_this).val; + r = s >> _ftb; + ret = -1; + loop { + t = s; + ret += 1; + s = r.wrapping_mul(*_icdf.offset(ret as isize) as u32); + if !(d < s) { + break; + } + } + (*_this).val = d.wrapping_sub(s); + (*_this).rng = t.wrapping_sub(s); + ec_dec_normalize(_this); + return ret; + } + pub unsafe fn ec_dec_uint(mut _this: &mut ec_dec, mut _ft: u32) -> u32 { + let mut ft: u32 = 0; + let mut s: u32 = 0; + let mut ftb: i32 = 0; + _ft = _ft.wrapping_sub(1); + ftb = ::core::mem::size_of::() as u64 as i32 + * 8 + - _ft.leading_zeros() as i32; + if ftb > 8 { + let mut t: u32 = 0; + ftb -= 8; + ft = (_ft >> ftb).wrapping_add(1); + s = ec_decode(_this, ft); + ec_dec_update( + _this, + s, + s.wrapping_add(1), + ft, + ); + t = s << ftb | ec_dec_bits(_this, ftb as u32); + if t <= _ft { + return t; + } + (*_this).error = 1; + return _ft; + } else { + _ft = _ft.wrapping_add(1); + s = ec_decode(_this, _ft); + ec_dec_update( + _this, + s, + s.wrapping_add(1), + _ft, + ); + return s; + }; + } + pub unsafe fn ec_dec_bits(mut _this: &mut ec_dec, mut _bits: u32) -> u32 { + let mut window: ec_window = 0; + let mut available: i32 = 0; + let mut ret: u32 = 0; + window = (*_this).end_window; + available = (*_this).nend_bits; + if (available as u32) < _bits { + loop { + window |= (ec_read_byte_from_end(_this) as ec_window) << available; + available += 8; + if !(available + <= ::core::mem::size_of::() as u64 as i32 + * 8 + - 8) + { + break; + } + } + } + ret = window & ((1) << _bits).wrapping_sub(1 as u32); + window >>= _bits; + available = (available as u32).wrapping_sub(_bits) as i32 as i32; + (*_this).end_window = window; + (*_this).nend_bits = available; + (*_this).nbits_total = ((*_this).nbits_total as u32).wrapping_add(_bits) + as i32 as i32; + return ret; + } + use super::entcode_h::{celt_udiv, ec_dec, ec_window}; +} +pub mod entcode_c { + pub unsafe fn ec_tell_frac(mut _this: *mut ec_ctx) -> u32 { + pub static mut correction: [u32; 8] = [ + 35733, + 38967, + 42495, + 46340, + 50535, + 55109, + 60097, + 65535, + ]; + let mut nbits: u32 = 0; + let mut r: u32 = 0; + let mut l: i32 = 0; + let mut b: u32 = 0; + nbits = ((*_this).nbits_total << 3) as u32; + l = ::core::mem::size_of::() as u64 as i32 + * 8 + - ((*_this).rng).leading_zeros() as i32; + r = (*_this).rng >> l - 16; + b = (r >> 12).wrapping_sub(8); + b = b.wrapping_add((r > correction[b as usize]) as i32 as u32); + l = ((l << 3) as u32).wrapping_add(b) as i32; + return nbits.wrapping_sub(l as u32); + } + use super::entcode_h::ec_ctx; +} +pub mod laplace_c { + pub unsafe fn ec_laplace_get_freq1( + mut fs0: u32, + mut decay: i32, + ) -> u32 { + let mut ft: u32 = 0; + ft = ((32768 + - ((1) << 0) * (2 * 16)) + as u32) + .wrapping_sub(fs0); + return ft.wrapping_mul((16384 - decay) as u32) + >> 15; + } + pub unsafe fn ec_laplace_encode( + mut enc: *mut ec_enc, + mut value: *mut i32, + mut fs: u32, + mut decay: i32, + ) { + let mut fl: u32 = 0; + let mut val: i32 = *value; + fl = 0; + if val != 0 { + let mut s: i32 = 0; + let mut i: i32 = 0; + s = -((val < 0) as i32); + val = val + s ^ s; + fl = fs; + fs = ec_laplace_get_freq1(fs, decay); + i = 1; + while fs > 0 && i < val { + fs = fs.wrapping_mul(2); + fl = fl.wrapping_add(fs.wrapping_add( + (2 * ((1) << 0)) as u32, + )); + fs = fs.wrapping_mul(decay as u32) >> 15; + i += 1; + } + if fs == 0 { + let mut di: i32 = 0; + let mut ndi_max: i32 = 0; + ndi_max = ((32768) + .wrapping_sub(fl) + .wrapping_add(((1) << 0) as u32) + .wrapping_sub(1) + >> 0) as i32; + ndi_max = ndi_max - s >> 1; + di = if val - i < ndi_max - 1 { + val - i + } else { + ndi_max - 1 + }; + fl = fl.wrapping_add( + ((2 * di + 1 + s) + * ((1) << 0)) + as u32, + ); + fs = if (((1) << 0) as u32) + < (32768).wrapping_sub(fl) + { + ((1) << 0) as u32 + } else { + (32768).wrapping_sub(fl) + }; + *value = i + di + s ^ s; + } else { + fs = fs.wrapping_add(((1) << 0) as u32); + fl = fl.wrapping_add(fs & !s as u32); + } + } + ec_encode_bin( + enc, + fl, + fl.wrapping_add(fs), + 15, + ); + } + pub unsafe fn ec_laplace_decode( + mut dec: &mut ec_dec, + mut fs: u32, + mut decay: i32, + ) -> i32 { + let mut val: i32 = 0; + let mut fl: u32 = 0; + let mut fm: u32 = 0; + fm = ec_decode_bin(dec, 15); + fl = 0; + if fm >= fs { + val += 1; + fl = fs; + fs = (ec_laplace_get_freq1(fs, decay)) + .wrapping_add(((1) << 0) as u32); + while fs > ((1) << 0) as u32 + && fm >= fl.wrapping_add((2).wrapping_mul(fs)) + { + fs = fs.wrapping_mul(2); + fl = fl.wrapping_add(fs); + fs = fs + .wrapping_sub( + (2 * ((1) << 0)) + as u32, + ) + .wrapping_mul(decay as u32) + >> 15; + fs = fs.wrapping_add(((1) << 0) as u32); + val += 1; + } + if fs <= ((1) << 0) as u32 { + let mut di: i32 = 0; + di = (fm.wrapping_sub(fl) >> 0 + 1) as i32; + val += di; + fl = fl.wrapping_add( + (2 * di * ((1) << 0)) + as u32, + ); + } + if fm < fl.wrapping_add(fs) { + val = -val; + } else { + fl = fl.wrapping_add(fs); + } + } + ec_dec_update( + dec, + fl, + if fl.wrapping_add(fs) < 32768 { + fl.wrapping_add(fs) + } else { + 32768 + }, + 32768, + ); + return val; + } + use super::entcode_h::{ec_dec, ec_enc}; + use super::entdec_c::{ec_dec_update, ec_decode_bin}; + use super::entenc_c::ec_encode_bin; +} +pub use self::entcode_c::ec_tell_frac; +pub use self::entcode_h::{ + celt_udiv, ec_ctx, ec_dec, ec_enc, ec_get_buffer, ec_range_bytes, ec_window, +}; +pub use self::entdec_c::{ + ec_dec_bit_logp, ec_dec_bits, ec_dec_icdf, ec_dec_init, ec_dec_normalize, ec_dec_uint, + ec_dec_update, ec_decode, ec_decode_bin, ec_read_byte, ec_read_byte_from_end, +}; +pub use self::entenc_c::{ + ec_enc_bit_logp, ec_enc_bits, ec_enc_carry_out, ec_enc_done, ec_enc_icdf, ec_enc_init, + ec_enc_normalize, ec_enc_patch_initial_bits, ec_enc_shrink, ec_enc_uint, ec_encode, + ec_encode_bin, ec_write_byte, ec_write_byte_at_end, +}; +pub use self::laplace_c::{ec_laplace_decode, ec_laplace_encode, ec_laplace_get_freq1}; +pub use self::stddef_h::size_t; + +use self::stdio_h::{fprintf, stderr}; +use self::stdlib_h::{free, malloc, rand}; +pub use self::struct_FILE_h::{_IO_codecvt, _IO_lock_t, _IO_marker, _IO_wide_data, _IO_FILE}; + +pub use self::FILE_h::FILE; +use crate::externs::{memmove, memset}; +pub unsafe fn ec_laplace_get_start_freq(mut decay: i32) -> i32 { + let mut ft: u32 = (32768 + - ((1) << 0) + * (2 * 16 + 1)) + as u32; + let mut fs: i32 = + ft.wrapping_mul((16384 - decay) as u32) + .wrapping_div((16384 + decay) as u32) as i32; + return fs + ((1) << 0); +} +unsafe fn main_0() -> i32 { + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut enc: ec_enc = ec_enc { + buf: 0 as *mut u8, + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut dec: ec_dec = ec_enc { + buf: 0 as *mut u8, + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut ptr: *mut u8 = 0 as *mut u8; + let mut val: [i32; 10000] = [0; 10000]; + let mut decay: [i32; 10000] = [0; 10000]; + ptr = malloc(40000) as *mut u8; + ec_enc_init(&mut enc, ptr, 40000); + val[0 as usize] = 3; + decay[0 as usize] = 6000; + val[1 as usize] = 0; + decay[1 as usize] = 5800; + val[2 as usize] = -1; + decay[2 as usize] = 5600; + i = 3; + while i < 10000 { + val[i as usize] = rand() % 15 - 7; + decay[i as usize] = rand() % 11000 + 5000; + i += 1; + } + i = 0; + while i < 10000 { + ec_laplace_encode( + &mut enc, + &mut *val.as_mut_ptr().offset(i as isize), + ec_laplace_get_start_freq(decay[i as usize]) as u32, + decay[i as usize], + ); + i += 1; + } + ec_enc_done(&mut enc); + ec_dec_init(dec, ec_get_buffer(&mut enc), ec_range_bytes(&mut enc)); + i = 0; + while i < 10000 { + let mut d: i32 = ec_laplace_decode( + dec, + ec_laplace_get_start_freq(decay[i as usize]) as u32, + decay[i as usize], + ); + if d != val[i as usize] { + fprintf( + stderr(), + b"Got %d instead of %d\n\0" as *const u8 as *const i8, + d, + val[i as usize], + ); + ret = 1; + } + i += 1; + } + free(ptr as *mut core::ffi::c_void); + return ret; +} +pub fn main() { + unsafe { ::std::process::exit(main_0() as i32) } +} diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_mathops.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_mathops.rs new file mode 100644 index 00000000..61899d5e --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_mathops.rs @@ -0,0 +1,248 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + } +} +pub mod mathcalls_h { + { + pub fn exp(_: f64) -> f64; + pub fn log(_: f64) -> f64; + pub fn sqrt(_: f64) -> f64; + pub fn fabs(_: f64) -> f64; + } +} +use self::arch_h::{opus_val16, opus_val32}; +use self::bands_h::{bitexact_cos, bitexact_log2tan}; +use self::mathcalls_h::{exp, fabs, log, sqrt}; +pub use self::stddef_h::size_t; + +use self::stdio_h::{fprintf, stderr}; +pub use self::struct_FILE_h::{_IO_codecvt, _IO_lock_t, _IO_marker, _IO_wide_data, _IO_FILE}; + +pub use self::FILE_h::FILE; +pub static mut ret: i32 = 0; +pub unsafe fn testdiv() { + let mut i: i32 = 0; + i = 1; + while i <= 327670 { + let mut prod: f64 = 0.; + let mut val: opus_val32 = 0.; + val = 1.0f32 / i as f32; + prod = (val * i as f32) as f64; + if fabs(prod - 1 as f64) > 0.00025f64 { + fprintf( + stderr(), + b"div failed: 1/%d=%f (product = %f)\n\0" as *const u8 as *const i8, + i, + val as f64, + prod, + ); + ret = 1; + } + i += 1; + } +} +pub unsafe fn testsqrt() { + let mut i: i32 = 0; + i = 1; + while i <= 1000000000 { + let mut ratio: f64 = 0.; + let mut val: opus_val16 = 0.; + val = sqrt(i as f64) as f32; + ratio = val as f64 / sqrt(i as f64); + if fabs(ratio - 1 as f64) > 0.0005f64 + && fabs(val as f64 - sqrt(i as f64)) + > 2 as f64 + { + fprintf( + stderr(), + b"sqrt failed: sqrt(%d)=%f (ratio = %f)\n\0" as *const u8 as *const i8, + i, + val as f64, + ratio, + ); + ret = 1; + } + i += i >> 10; + i += 1; + } +} +pub unsafe fn testbitexactcos() { + let mut i: i32 = 0; + let mut min_d: i32 = 0; + let mut max_d: i32 = 0; + let mut last: i32 = 0; + let mut chk: i32 = 0; + max_d = 0; + chk = max_d; + min_d = 32767; + last = min_d; + i = 64; + while i <= 16320 { + let mut d: i32 = 0; + let mut q: i32 = bitexact_cos(i as i16) as i32; + chk ^= q * i; + d = last - q; + if d > max_d { + max_d = d; + } + if d < min_d { + min_d = d; + } + last = q; + i += 1; + } + if chk != 89408644 + || max_d != 5 + || min_d != 0 + || bitexact_cos(64) as i32 != 32767 + || bitexact_cos(16320) as i32 != 200 + || bitexact_cos(8192) as i32 != 23171 + { + fprintf( + stderr(), + b"bitexact_cos failed\n\0" as *const u8 as *const i8, + ); + ret = 1; + } +} +pub unsafe fn testbitexactlog2tan() { + let mut i: i32 = 0; + let mut fail: i32 = 0; + let mut min_d: i32 = 0; + let mut max_d: i32 = 0; + let mut last: i32 = 0; + let mut chk: i32 = 0; + max_d = 0; + chk = max_d; + fail = chk; + min_d = 15059; + last = min_d; + i = 64; + while i < 8193 { + let mut d: i32 = 0; + let mut mid: i32 = bitexact_cos(i as i16) as i32; + let mut side: i32 = bitexact_cos((16384 - i) as i16) as i32; + let mut q: i32 = bitexact_log2tan(mid, side); + chk ^= q * i; + d = last - q; + if q != -1 * bitexact_log2tan(side, mid) { + fail = 1; + } + if d > max_d { + max_d = d; + } + if d < min_d { + min_d = d; + } + last = q; + i += 1; + } + if chk != 15821257 + || max_d != 61 + || min_d != -(2) + || fail != 0 + || bitexact_log2tan(32767, 200) != 15059 + || bitexact_log2tan(30274, 12540) != 2611 + || bitexact_log2tan(23171, 23171) != 0 + { + fprintf( + stderr(), + b"bitexact_log2tan failed\n\0" as *const u8 as *const i8, + ); + ret = 1; + } +} +pub unsafe fn testlog2() { + let mut x: f32 = 0.; + x = 0.001f64 as f32; + while (x as f64) < 1677700.0f64 { + let mut error: f32 = fabs( + 1.442695040888963387f64 * log(x as f64) + - (1.442695040888963387f64 * log(x as f64)) as f32 + as f64, + ) as f32; + if error as f64 > 0.0009f64 { + fprintf( + stderr(), + b"celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n\0" + as *const u8 as *const i8, + x as f64, + error as f64, + ); + ret = 1; + } + x = (x as f64 + x as f64 / 8.0f64) as f32; + } +} +pub unsafe fn testexp2() { + let mut x: f32 = 0.; + x = -11.0f64 as f32; + while (x as f64) < 24.0f64 { + let mut error: f32 = fabs( + x as f64 + - 1.442695040888963387f64 + * log( + exp(0.6931471805599453094f64 * x as f64) as f32 + as f64, + ), + ) as f32; + if error as f64 > 0.0002f64 { + fprintf( + stderr(), + b"celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n\0" + as *const u8 as *const i8, + x as f64, + error as f64, + ); + ret = 1; + } + x = (x as f64 + 0.0007f64) as f32; + } +} +pub unsafe fn testexp2log2() { + let mut x: f32 = 0.; + x = -11.0f64 as f32; + while (x as f64) < 24.0f64 { + let mut error: f32 = fabs( + (x - (1.442695040888963387f64 + * log( + exp(0.6931471805599453094f64 * x as f64) as f32 + as f64, + )) as f32) as f64, + ) as f32; + if error as f64 > 0.001f64 { + fprintf( + stderr(), + b"celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n\0" + as *const u8 as *const i8, + x as f64, + error as f64, + ); + ret = 1; + } + x = (x as f64 + 0.0007f64) as f32; + } +} +unsafe fn main_0() -> i32 { + testbitexactcos(); + testbitexactlog2tan(); + testdiv(); + testsqrt(); + testlog2(); + testexp2(); + testexp2log2(); + return ret; +} +pub fn main() { + unsafe { ::std::process::exit(main_0() as i32) } +} diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_mdct.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_mdct.rs new file mode 100644 index 00000000..ef7e53e0 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_mdct.rs @@ -0,0 +1,415 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod arch_h { + pub type opus_val16 = f32; +} +pub mod kiss_fft_h { + #[derive(Copy, Clone)] + #[repr(C)] + pub struct kiss_twiddle_cpx { + pub r: f32, + pub i: f32, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct arch_fft_state { + pub is_supported: i32, + pub priv_0: *mut core::ffi::c_void, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct kiss_fft_state { + pub nfft: i32, + pub scale: opus_val16, + pub shift: i32, + pub factors: [i16; 16], + pub bitrev: *const i16, + pub twiddles: *const kiss_twiddle_cpx, + pub arch_fft: *mut arch_fft_state, + } + use super::arch_h::opus_val16; +} +pub mod mdct_h { + #[derive(Copy, Clone)] + #[repr(C)] + pub struct mdct_lookup { + pub n: i32, + pub maxshift: i32, + pub kfft: [*const kiss_fft_state; 4], + pub trig: *const f32, + } + use super::arch_h::opus_val16; + use super::kiss_fft_h::kiss_fft_state; + { + pub fn clt_mdct_backward_c( + l: *const mdct_lookup, + in_0: *mut f32, + out: *mut f32, + window: *const opus_val16, + overlap: i32, + shift: i32, + stride: i32, + arch: i32, + ); + pub fn clt_mdct_forward_c( + l: *const mdct_lookup, + in_0: *mut f32, + out: *mut f32, + window: *const opus_val16, + overlap: i32, + shift: i32, + stride: i32, + arch: i32, + ); + } +} +pub mod modes_h { + #[derive(Copy, Clone)] + #[repr(C)] + pub struct OpusCustomMode { + pub Fs: i32, + pub overlap: i32, + pub nbEBands: i32, + pub effEBands: i32, + pub preemph: [opus_val16; 4], + pub eBands: *const i16, + pub maxLM: i32, + pub nbShortMdcts: i32, + pub shortMdctSize: i32, + pub nbAllocVectors: i32, + pub allocVectors: *const u8, + pub logN: *const i16, + pub window: *const opus_val16, + pub mdct: mdct_lookup, + pub cache: PulseCache, + } + #[derive(Copy, Clone)] + #[repr(C)] + pub struct PulseCache { + pub size: i32, + pub index: *const i16, + pub bits: *const u8, + pub caps: *const u8, + } + use super::arch_h::opus_val16; + use crate::celt::mdct::mdct_lookup; +} +pub mod stdio_h { + { + pub fn printf(_: *const i8, _: ...) -> i32; + } +} +pub mod mathcalls_h { + { + pub fn cos(_: f64) -> f64; + pub fn log10(_: f64) -> f64; + } +} +pub mod stdlib_h { + #[inline] + pub unsafe fn atoi(mut __nptr: *const i8) -> i32 { + return strtol( + __nptr, + 0 as *mut core::ffi::c_void as *mut *mut i8, + 10, + ) as i32; + } + { + pub fn rand() -> i32; + pub fn malloc(_: u64) -> *mut core::ffi::c_void; + pub fn free(_: *mut core::ffi::c_void); + pub fn strtol( + _: *const i8, + _: *mut *mut i8, + _: i32, + ) -> i64; + } +} +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub mod opus_custom_h { + use super::modes_h::OpusCustomMode; + { + pub fn opus_custom_mode_create( + Fs: i32, + frame_size: i32, + error: *mut i32, + ) -> *mut OpusCustomMode; + } +} +pub use self::arch_h::opus_val16; +pub use self::cpu_support_h::opus_select_arch; +pub use self::kiss_fft_h::{arch_fft_state, kiss_fft_state, kiss_twiddle_cpx}; +use self::mathcalls_h::{cos, log10}; +pub use self::mdct_h::{clt_mdct_backward_c, clt_mdct_forward_c, mdct_lookup}; +pub use self::modes_h::{OpusCustomMode, PulseCache}; +use self::opus_custom_h::opus_custom_mode_create; +pub use self::stddef_h::size_t; + +use self::stdio_h::printf; +pub use self::stdlib_h::{atoi, free, malloc, rand, strtol}; + +pub static mut ret: i32 = 0; +pub unsafe fn check( + mut in_0: *mut f32, + mut out: *mut f32, + mut nfft: i32, + mut isinverse: i32, +) { + let mut bin: i32 = 0; + let mut k: i32 = 0; + let mut errpow: f64 = 0 as f64; + let mut sigpow: f64 = 0 as f64; + let mut snr: f64 = 0.; + bin = 0; + while bin < nfft / 2 { + let mut ansr: f64 = 0 as f64; + let mut difr: f64 = 0.; + k = 0; + while k < nfft { + let mut phase: f64 = 2 as f64 + * 3.14159265358979323846f64 + * (k as f64 + 0.5f64 + 0.25f64 * nfft as f64) + * (bin as f64 + 0.5f64) + / nfft as f64; + let mut re: f64 = cos(phase); + re /= (nfft / 4) as f64; + ansr += *in_0.offset(k as isize) as f64 * re; + k += 1; + } + difr = ansr - *out.offset(bin as isize) as f64; + errpow += difr * difr; + sigpow += ansr * ansr; + bin += 1; + } + snr = 10 as f64 * log10(sigpow / errpow); + printf( + b"nfft=%d inverse=%d,snr = %f\n\0" as *const u8 as *const i8, + nfft, + isinverse, + snr, + ); + if snr < 60 as f64 { + printf( + b"** poor snr: %f **\n\0" as *const u8 as *const i8, + snr, + ); + ret = 1; + } +} +pub unsafe fn check_inv( + mut in_0: *mut f32, + mut out: *mut f32, + mut nfft: i32, + mut isinverse: i32, +) { + let mut bin: i32 = 0; + let mut k: i32 = 0; + let mut errpow: f64 = 0 as f64; + let mut sigpow: f64 = 0 as f64; + let mut snr: f64 = 0.; + bin = 0; + while bin < nfft { + let mut ansr: f64 = 0 as f64; + let mut difr: f64 = 0.; + k = 0; + while k < nfft / 2 { + let mut phase: f64 = 2 as f64 + * 3.14159265358979323846f64 + * (bin as f64 + 0.5f64 + 0.25f64 * nfft as f64) + * (k as f64 + 0.5f64) + / nfft as f64; + let mut re: f64 = cos(phase); + ansr += *in_0.offset(k as isize) as f64 * re; + k += 1; + } + difr = ansr - *out.offset(bin as isize) as f64; + errpow += difr * difr; + sigpow += ansr * ansr; + bin += 1; + } + snr = 10 as f64 * log10(sigpow / errpow); + printf( + b"nfft=%d inverse=%d,snr = %f\n\0" as *const u8 as *const i8, + nfft, + isinverse, + snr, + ); + if snr < 60 as f64 { + printf( + b"** poor snr: %f **\n\0" as *const u8 as *const i8, + snr, + ); + ret = 1; + } +} +pub unsafe fn test1d( + mut nfft: i32, + mut isinverse: i32, + mut arch: i32, +) { + let mut buflen: size_t = (::core::mem::size_of::() as u64) + .wrapping_mul(nfft as u64); + let mut in_0: *mut f32 = 0 as *mut f32; + let mut in_copy: *mut f32 = 0 as *mut f32; + let mut out: *mut f32 = 0 as *mut f32; + let mut window: *mut opus_val16 = 0 as *mut opus_val16; + let mut k: i32 = 0; + let mut shift: i32 = 0; + let mut cfg: *const mdct_lookup = 0 as *const mdct_lookup; + let mut mode: *mut OpusCustomMode = opus_custom_mode_create( + 48000, + 960, + 0 as *mut i32, + ); + if nfft == 1920 { + shift = 0; + } else if nfft == 960 { + shift = 1; + } else if nfft == 480 { + shift = 2; + } else if nfft == 240 { + shift = 3; + } else { + return; + } + cfg = &mut (*mode).mdct; + in_0 = malloc(buflen) as *mut f32; + in_copy = malloc(buflen) as *mut f32; + out = malloc(buflen) as *mut f32; + window = malloc( + (::core::mem::size_of::() as u64) + .wrapping_mul(nfft as u64) + .wrapping_div(2), + ) as *mut opus_val16; + k = 0; + while k < nfft { + *in_0.offset(k as isize) = + (rand() % 32768 - 16384) as f32; + k += 1; + } + k = 0; + while k < nfft / 2 { + *window.offset(k as isize) = 1.0f32; + k += 1; + } + k = 0; + while k < nfft { + *in_0.offset(k as isize) *= 32768 as f32; + k += 1; + } + if isinverse != 0 { + k = 0; + while k < nfft { + *in_0.offset(k as isize) /= nfft as f32; + k += 1; + } + } + k = 0; + while k < nfft { + *in_copy.offset(k as isize) = *in_0.offset(k as isize); + k += 1; + } + if isinverse != 0 { + k = 0; + while k < nfft { + *out.offset(k as isize) = 0 as f32; + k += 1; + } + clt_mdct_backward_c( + cfg, + in_0, + out, + window, + nfft / 2, + shift, + 1, + arch, + ); + k = 0; + while k < nfft / 4 { + *out.offset((nfft - k - 1) as isize) = + *out.offset((nfft / 2 + k) as isize); + k += 1; + } + check_inv(in_0, out, nfft, isinverse); + } else { + clt_mdct_forward_c( + cfg, + in_0, + out, + window, + nfft / 2, + shift, + 1, + arch, + ); + check(in_copy, out, nfft, isinverse); + } + free(in_0 as *mut core::ffi::c_void); + free(in_copy as *mut core::ffi::c_void); + free(out as *mut core::ffi::c_void); + free(window as *mut core::ffi::c_void); +} +unsafe fn main_0(mut argc: i32, mut argv: *mut *mut i8) -> i32 { + let mut arch: i32 = opus_select_arch(); + if argc > 1 { + let mut k: i32 = 0; + k = 1; + while k < argc { + test1d(atoi(*argv.offset(k as isize)), 0, arch); + test1d(atoi(*argv.offset(k as isize)), 1, arch); + k += 1; + } + } else { + test1d(32, 0, arch); + test1d(32, 1, arch); + test1d(256, 0, arch); + test1d(256, 1, arch); + test1d(512, 0, arch); + test1d(512, 1, arch); + test1d(1024, 0, arch); + test1d(1024, 1, arch); + test1d(2048, 0, arch); + test1d(2048, 1, arch); + test1d(36, 0, arch); + test1d(36, 1, arch); + test1d(40, 0, arch); + test1d(40, 1, arch); + test1d(60, 0, arch); + test1d(60, 1, arch); + test1d(120, 0, arch); + test1d(120, 1, arch); + test1d(240, 0, arch); + test1d(240, 1, arch); + test1d(480, 0, arch); + test1d(480, 1, arch); + test1d(960, 0, arch); + test1d(960, 1, arch); + test1d(1920, 0, arch); + test1d(1920, 1, arch); + } + return ret; +} +pub fn main() { + let mut args: Vec<*mut i8> = Vec::new(); + for arg in ::std::env::args() { + args.push( + (::std::ffi::CString::new(arg)) + .expect("Failed to convert argument into CString.") + .into_raw(), + ); + } + args.push(::core::ptr::null_mut()); + unsafe { + ::std::process::exit(main_0( + (args.len() - 1) as i32, + args.as_mut_ptr() as *mut *mut i8, + ) as i32) + } +} diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_rotation.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_rotation.rs new file mode 100644 index 00000000..e0b0bafb --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_rotation.rs @@ -0,0 +1,119 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod arch_h { + pub type opus_val16 = f32; + pub type celt_norm = f32; +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + pub fn printf(_: *const i8, _: ...) -> i32; + } +} +pub mod stdlib_h { + { + pub fn rand() -> i32; + } +} +pub mod mathcalls_h { + { + pub fn log10(_: f64) -> f64; + } +} +pub mod vq_h { + use super::arch_h::celt_norm; + { + pub fn exp_rotation( + X: *mut celt_norm, + len: i32, + dir: i32, + stride: i32, + K: i32, + spread: i32, + ); + } +} +pub use self::arch_h::{celt_norm, opus_val16}; +use self::mathcalls_h::log10; +pub use self::stddef_h::size_t; +use self::stdio_h::{fprintf, printf, stderr}; +use self::stdlib_h::rand; +pub use self::struct_FILE_h::{_IO_codecvt, _IO_lock_t, _IO_marker, _IO_wide_data, _IO_FILE}; + +use self::vq_h::exp_rotation; +pub use self::FILE_h::FILE; +pub static mut ret: i32 = 0; +pub unsafe fn test_rotation(mut N: i32, mut K: i32) { + let mut i: i32 = 0; + let mut err: f64 = 0 as f64; + let mut ener: f64 = 0 as f64; + let mut snr: f64 = 0.; + let mut snr0: f64 = 0.; + let mut x0: [opus_val16; 100] = [0.; 100]; + let mut x1: [opus_val16; 100] = [0.; 100]; + i = 0; + while i < N { + x0[i as usize] = (rand() % 32767 - 16384) as opus_val16; + x1[i as usize] = x0[i as usize]; + i += 1; + } + exp_rotation( + x1.as_mut_ptr(), + N, + 1, + 1, + K, + 2, + ); + i = 0; + while i < N { + err += (x0[i as usize] as f64 - x1[i as usize] as f64) + * (x0[i as usize] as f64 - x1[i as usize] as f64); + ener += x0[i as usize] as f64 * x0[i as usize] as f64; + i += 1; + } + snr0 = 20 as f64 * log10(ener / err); + ener = 0 as f64; + err = ener; + exp_rotation( + x1.as_mut_ptr(), + N, + -1, + 1, + K, + 2, + ); + i = 0; + while i < N { + err += (x0[i as usize] as f64 - x1[i as usize] as f64) + * (x0[i as usize] as f64 - x1[i as usize] as f64); + ener += x0[i as usize] as f64 * x0[i as usize] as f64; + i += 1; + } + snr = 20 as f64 * log10(ener / err); + printf( + b"SNR for size %d (%d pulses) is %f (was %f without inverse)\n\0" as *const u8 + as *const i8, + N, + K, + snr, + snr0, + ); + if snr < 60 as f64 || snr0 > 20 as f64 { + fprintf(stderr(), b"FAIL!\n\0" as *const u8 as *const i8); + ret = 1; + } +} +unsafe fn main_0() -> i32 { + test_rotation(15, 3); + test_rotation(23, 5); + test_rotation(50, 3); + test_rotation(80, 1); + return ret; +} +pub fn main() { + unsafe { ::std::process::exit(main_0() as i32) } +} diff --git a/vendor/unsafe-libopus/src/celt/tests/test_unit_types.rs b/vendor/unsafe-libopus/src/celt/tests/test_unit_types.rs new file mode 100644 index 00000000..287e18e3 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/tests/test_unit_types.rs @@ -0,0 +1,41 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + } +} +pub use self::stddef_h::size_t; + +use self::stdio_h::{fprintf, stderr}; +pub use self::struct_FILE_h::{_IO_codecvt, _IO_lock_t, _IO_marker, _IO_wide_data, _IO_FILE}; + +pub use self::FILE_h::FILE; +unsafe fn main_0() -> i32 { + let mut i: i16 = 1; + i = ((i as i32) << 14) as i16; + if i as i32 >> 14 != 1 { + fprintf( + stderr(), + b"i16 isn't 16 bits\n\0" as *const u8 as *const i8, + ); + return 1; + } + if (::core::mem::size_of::() as u64) + .wrapping_mul(2) + != ::core::mem::size_of::() as u64 + { + fprintf( + stderr(), + b"16*2 != 32\n\0" as *const u8 as *const i8, + ); + return 1; + } + return 0; +} +pub fn main() { + unsafe { ::std::process::exit(main_0() as i32) } +} diff --git a/vendor/unsafe-libopus/src/celt/vq.rs b/vendor/unsafe-libopus/src/celt/vq.rs new file mode 100644 index 00000000..10485163 --- /dev/null +++ b/vendor/unsafe-libopus/src/celt/vq.rs @@ -0,0 +1,371 @@ +use crate::celt::bands::SPREAD_NONE; +use std::f32::consts::PI; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub type celt_norm = f32; + pub const EPSILON: f32 = 1e-15f32; +} +use self::arch_h::{celt_norm, opus_val16, opus_val32, EPSILON}; +use crate::celt::cwrs::{decode_pulses, encode_pulses}; +use crate::celt::entcode::celt_udiv; +use crate::celt::entdec::ec_dec; +use crate::celt::entenc::ec_enc; +use crate::celt::mathops::{celt_cos_norm, celt_rsqrt_norm, celt_sqrt, fast_atan2f}; +use crate::celt::pitch::celt_inner_prod_c; + +unsafe fn exp_rotation1(X: *mut celt_norm, len: i32, stride: i32, c: opus_val16, s: opus_val16) { + let mut i: i32 = 0; + let mut ms: opus_val16 = 0.; + let mut Xptr: *mut celt_norm = 0 as *mut celt_norm; + Xptr = X; + ms = -s; + i = 0; + while i < len - stride { + let mut x1: celt_norm = 0.; + let mut x2: celt_norm = 0.; + x1 = *Xptr.offset(0 as isize); + x2 = *Xptr.offset(stride as isize); + *Xptr.offset(stride as isize) = c * x2 + s * x1; + let fresh0 = Xptr; + Xptr = Xptr.offset(1); + *fresh0 = c * x1 + ms * x2; + i += 1; + } + Xptr = &mut *X.offset((len - 2 * stride - 1) as isize) as *mut celt_norm; + i = len - 2 * stride - 1; + while i >= 0 { + let mut x1_0: celt_norm = 0.; + let mut x2_0: celt_norm = 0.; + x1_0 = *Xptr.offset(0 as isize); + x2_0 = *Xptr.offset(stride as isize); + *Xptr.offset(stride as isize) = c * x2_0 + s * x1_0; + let fresh1 = Xptr; + Xptr = Xptr.offset(-1); + *fresh1 = c * x1_0 + ms * x2_0; + i -= 1; + } +} +pub unsafe fn exp_rotation( + X: *mut celt_norm, + mut len: i32, + dir: i32, + stride: i32, + K: i32, + spread: i32, +) { + static SPREAD_FACTOR: [i32; 3] = [15, 10, 5]; + let mut i: i32 = 0; + let mut c: opus_val16 = 0.; + let mut s: opus_val16 = 0.; + let mut gain: opus_val16 = 0.; + let mut theta: opus_val16 = 0.; + let mut stride2: i32 = 0; + let mut factor: i32 = 0; + if 2 * K >= len || spread == SPREAD_NONE { + return; + } + factor = SPREAD_FACTOR[(spread - 1) as usize]; + gain = 1.0f32 * len as opus_val32 / (len + factor * K) as opus_val32; + theta = 0.5f32 * (gain * gain); + c = celt_cos_norm(theta); + s = celt_cos_norm(1.0f32 - theta); + if len >= 8 * stride { + stride2 = 1; + while (stride2 * stride2 + stride2) * stride + (stride >> 2) < len { + stride2 += 1; + } + } + len = celt_udiv(len as u32, stride as u32) as i32; + i = 0; + while i < stride { + if dir < 0 { + if stride2 != 0 { + exp_rotation1(X.offset((i * len) as isize), len, stride2, s, c); + } + exp_rotation1(X.offset((i * len) as isize), len, 1, c, s); + } else { + exp_rotation1(X.offset((i * len) as isize), len, 1, c, -s); + if stride2 != 0 { + exp_rotation1(X.offset((i * len) as isize), len, stride2, s, -c); + } + } + i += 1; + } +} +unsafe fn normalise_residual( + iy: *mut i32, + X: *mut celt_norm, + N: i32, + Ryy: opus_val32, + gain: opus_val16, +) { + let mut i: i32 = 0; + let mut t: opus_val32 = 0.; + let mut g: opus_val16 = 0.; + t = Ryy; + g = celt_rsqrt_norm(t) * gain; + i = 0; + loop { + *X.offset(i as isize) = g * *iy.offset(i as isize) as opus_val32; + i += 1; + if !(i < N) { + break; + } + } +} +unsafe fn extract_collapse_mask(iy: *mut i32, N: i32, B: i32) -> u32 { + let mut collapse_mask: u32 = 0; + let mut N0: i32 = 0; + let mut i: i32 = 0; + if B <= 1 { + return 1; + } + N0 = celt_udiv(N as u32, B as u32) as i32; + collapse_mask = 0; + i = 0; + loop { + let mut j: i32 = 0; + let mut tmp: u32 = 0; + j = 0; + loop { + tmp |= *iy.offset((i * N0 + j) as isize) as u32; + j += 1; + if !(j < N0) { + break; + } + } + collapse_mask |= (((tmp != 0) as i32) << i) as u32; + i += 1; + if !(i < B) { + break; + } + } + return collapse_mask; +} +pub unsafe fn op_pvq_search_c( + X: *mut celt_norm, + iy: *mut i32, + K: i32, + N: i32, + _arch: i32, +) -> opus_val16 { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut pulsesLeft: i32 = 0; + let mut sum: opus_val32 = 0.; + let mut xy: opus_val32 = 0.; + let mut yy: opus_val16 = 0.; + let vla = N as usize; + let mut y: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = N as usize; + let mut signx: Vec = ::std::vec::from_elem(0, vla_0); + sum = 0 as opus_val32; + j = 0; + loop { + *signx.as_mut_ptr().offset(j as isize) = (*X.offset(j as isize) < 0 as f32) as i32; + *X.offset(j as isize) = (*X.offset(j as isize)).abs(); + *iy.offset(j as isize) = 0; + *y.as_mut_ptr().offset(j as isize) = 0 as celt_norm; + j += 1; + if !(j < N) { + break; + } + } + yy = 0 as opus_val16; + xy = yy; + pulsesLeft = K; + if K > N >> 1 { + let mut rcp: opus_val16 = 0.; + j = 0; + loop { + sum += *X.offset(j as isize); + j += 1; + if !(j < N) { + break; + } + } + if !(sum > EPSILON && sum < 64 as f32) { + *X.offset(0 as isize) = 1.0f32; + j = 1; + loop { + *X.offset(j as isize) = 0 as celt_norm; + j += 1; + if !(j < N) { + break; + } + } + sum = 1.0f32; + } + rcp = (K as f32 + 0.8f32) * (1.0f32 / sum); + j = 0; + loop { + *iy.offset(j as isize) = (rcp * *X.offset(j as isize)).floor() as i32; + *y.as_mut_ptr().offset(j as isize) = *iy.offset(j as isize) as celt_norm; + yy = yy + *y.as_mut_ptr().offset(j as isize) * *y.as_mut_ptr().offset(j as isize); + xy = xy + *X.offset(j as isize) * *y.as_mut_ptr().offset(j as isize); + let ref mut fresh2 = *y.as_mut_ptr().offset(j as isize); + *fresh2 *= 2 as f32; + pulsesLeft -= *iy.offset(j as isize); + j += 1; + if !(j < N) { + break; + } + } + } + if pulsesLeft > N + 3 { + let tmp: opus_val16 = pulsesLeft as opus_val16; + yy = yy + tmp * tmp; + yy = yy + tmp * *y.as_mut_ptr().offset(0 as isize); + *iy.offset(0 as isize) += pulsesLeft; + pulsesLeft = 0; + } + i = 0; + while i < pulsesLeft { + let mut Rxy: opus_val16 = 0.; + let mut Ryy: opus_val16 = 0.; + let mut best_id: i32 = 0; + let mut best_num: opus_val32 = 0.; + let mut best_den: opus_val16 = 0.; + best_id = 0; + yy = yy + 1 as f32; + Rxy = xy + *X.offset(0 as isize); + Ryy = yy + *y.as_mut_ptr().offset(0 as isize); + Rxy = Rxy * Rxy; + best_den = Ryy; + best_num = Rxy; + j = 1; + loop { + Rxy = xy + *X.offset(j as isize); + Ryy = yy + *y.as_mut_ptr().offset(j as isize); + Rxy = Rxy * Rxy; + if (best_den * Rxy > Ryy * best_num) as i32 as i64 != 0 { + best_den = Ryy; + best_num = Rxy; + best_id = j; + } + j += 1; + if !(j < N) { + break; + } + } + xy = xy + *X.offset(best_id as isize); + yy = yy + *y.as_mut_ptr().offset(best_id as isize); + let ref mut fresh3 = *y.as_mut_ptr().offset(best_id as isize); + *fresh3 += 2 as f32; + let ref mut fresh4 = *iy.offset(best_id as isize); + *fresh4 += 1; + i += 1; + } + j = 0; + loop { + *iy.offset(j as isize) = (*iy.offset(j as isize) ^ -*signx.as_mut_ptr().offset(j as isize)) + + *signx.as_mut_ptr().offset(j as isize); + j += 1; + if !(j < N) { + break; + } + } + return yy; +} +pub unsafe fn alg_quant( + X: *mut celt_norm, + N: i32, + K: i32, + spread: i32, + B: i32, + enc: &mut ec_enc, + gain: opus_val16, + resynth: i32, + arch: i32, +) -> u32 { + let mut yy: opus_val16 = 0.; + let mut collapse_mask: u32 = 0; + assert!(K > 0); + assert!(N > 1); + let vla = (N + 3) as usize; + let mut iy: Vec = ::std::vec::from_elem(0, vla); + exp_rotation(X, N, 1, B, K, spread); + yy = op_pvq_search_c(X, iy.as_mut_ptr(), K, N, arch); + encode_pulses(iy.as_mut_ptr(), N, K, enc); + if resynth != 0 { + normalise_residual(iy.as_mut_ptr(), X, N, yy, gain); + exp_rotation(X, N, -1, B, K, spread); + } + collapse_mask = extract_collapse_mask(iy.as_mut_ptr(), N, B); + return collapse_mask; +} +pub unsafe fn alg_unquant( + X: *mut celt_norm, + N: i32, + K: i32, + spread: i32, + B: i32, + dec: &mut ec_dec, + gain: opus_val16, +) -> u32 { + let mut Ryy: opus_val32 = 0.; + let mut collapse_mask: u32 = 0; + assert!(K > 0); + assert!(N > 1); + let vla = N as usize; + let mut iy: Vec = ::std::vec::from_elem(0, vla); + Ryy = decode_pulses(iy.as_mut_ptr(), N, K, dec); + normalise_residual(iy.as_mut_ptr(), X, N, Ryy, gain); + exp_rotation(X, N, -1, B, K, spread); + collapse_mask = extract_collapse_mask(iy.as_mut_ptr(), N, B); + return collapse_mask; +} +pub unsafe fn renormalise_vector(X: *mut celt_norm, N: i32, gain: opus_val16, _arch: i32) { + let mut i: i32 = 0; + let mut E: opus_val32 = 0.; + let mut g: opus_val16 = 0.; + let mut t: opus_val32 = 0.; + let mut xptr: *mut celt_norm = 0 as *mut celt_norm; + E = EPSILON + celt_inner_prod_c(X, X, N); + t = E; + g = celt_rsqrt_norm(t) * gain; + xptr = X; + i = 0; + while i < N { + *xptr = g * *xptr; + xptr = xptr.offset(1); + i += 1; + } +} +pub unsafe fn stereo_itheta( + X: *const celt_norm, + Y: *const celt_norm, + stereo: i32, + N: i32, + _arch: i32, +) -> i32 { + let mut i: i32 = 0; + let mut itheta: i32 = 0; + let mut mid: opus_val16 = 0.; + let mut side: opus_val16 = 0.; + let mut Emid: opus_val32 = 0.; + let mut Eside: opus_val32 = 0.; + Eside = EPSILON; + Emid = Eside; + if stereo != 0 { + i = 0; + while i < N { + let mut m: celt_norm = 0.; + let mut s: celt_norm = 0.; + m = *X.offset(i as isize) + *Y.offset(i as isize); + s = *X.offset(i as isize) - *Y.offset(i as isize); + Emid = Emid + m * m; + Eside = Eside + s * s; + i += 1; + } + } else { + Emid += celt_inner_prod_c(X, X, N); + Eside += celt_inner_prod_c(Y, Y, N); + } + mid = celt_sqrt(Emid); + side = celt_sqrt(Eside); + itheta = (0.5f32 + 16384 as f32 * 0.63662f32 * fast_atan2f(side, mid)).floor() as i32; + return itheta; +} diff --git a/vendor/unsafe-libopus/src/externs.rs b/vendor/unsafe-libopus/src/externs.rs new file mode 100644 index 00000000..761651ef --- /dev/null +++ b/vendor/unsafe-libopus/src/externs.rs @@ -0,0 +1,104 @@ +//! Contains implementation for some common libc functions. +//! +//! This is used to avoid unnecessarily linking to libc. + +use core::mem::{self, MaybeUninit}; +use core::ptr; +use core::slice; +use std::alloc::{self as rust, Layout}; + +const HEADER: usize = mem::size_of::(); + +const MALLOC_ALIGN: usize = mem::align_of::(); + +/// Implement `malloc` in terms of rust's `alloc`. +/// +/// It stores the size of the allocation in the first 8 bytes of the allocation. +pub unsafe fn malloc(size: u64) -> *mut core::ffi::c_void { + let size = HEADER + size as usize; + let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN); + let memory = rust::alloc(layout); + if memory.is_null() { + rust::handle_alloc_error(layout); + } + memory.cast::().write(size); + let result = memory.add(HEADER).cast(); + result +} + +/// Malloc, but zero out the memory. +pub unsafe fn calloc(n: u64, size: u64) -> *mut core::ffi::c_void { + let mem = malloc(n * size); + ptr::write_bytes(mem, 0, (n * size) as usize); + mem +} + +pub unsafe fn realloc(ptr: *mut core::ffi::c_void, new_size: u64) -> *mut core::ffi::c_void { + if ptr.is_null() { + return calloc(1, new_size); + } + + let mut memory = ptr.cast::().sub(HEADER); + let size = memory.cast::().read(); + let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN); + let new_size = HEADER + new_size as usize; + memory = rust::realloc(memory, layout, new_size); + if memory.is_null() { + let layout = Layout::from_size_align_unchecked(new_size, MALLOC_ALIGN); + rust::handle_alloc_error(layout); + } + memory.cast::().write(new_size); + memory.add(HEADER).cast() +} + +pub unsafe fn free(ptr: *mut core::ffi::c_void) { + if ptr == ptr::null_mut() { + return; + } + + let memory = ptr.cast::().sub(HEADER); + let size = memory.cast::().read(); + let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN); + rust::dealloc(memory, layout); +} + +pub unsafe fn memcmp( + lhs: *const core::ffi::c_void, + rhs: *const core::ffi::c_void, + count: u64, +) -> i32 { + let lhs = slice::from_raw_parts(lhs.cast::(), count as usize); + let rhs = slice::from_raw_parts(rhs.cast::(), count as usize); + lhs.cmp(rhs) as i32 +} + +pub unsafe fn memcpy( + dest: *mut core::ffi::c_void, + src: *const core::ffi::c_void, + count: u64, +) -> *mut core::ffi::c_void { + ptr::copy_nonoverlapping( + src.cast::>(), + dest.cast::>(), + count as usize, + ); + dest +} + +pub unsafe fn memmove( + dest: *mut core::ffi::c_void, + src: *const core::ffi::c_void, + count: u64, +) -> *mut core::ffi::c_void { + ptr::copy( + src.cast::>(), + dest.cast::>(), + count as usize, + ); + dest +} + +pub unsafe fn memset(dest: *mut core::ffi::c_void, ch: i32, count: u64) -> *mut core::ffi::c_void { + ptr::write_bytes(dest.cast::(), ch as u8, count as usize); + dest +} diff --git a/vendor/unsafe-libopus/src/lib.rs b/vendor/unsafe-libopus/src/lib.rs new file mode 100644 index 00000000..8ae8a6e5 --- /dev/null +++ b/vendor/unsafe-libopus/src/lib.rs @@ -0,0 +1,291 @@ +// tinyclient patch: a crate patched in by path gets no lint capping (`--cap-lints allow`, which +// every registry dependency gets), so its transpiled code's warnings would be ours, and today's +// rustc refuses its implicit autorefs outright. +#![allow(warnings)] +#![allow(dangerous_implicit_autorefs)] +extern crate core; + +pub mod externs; +pub mod varargs; + +#[allow(non_camel_case_types)] +#[allow(non_snake_case)] +#[allow(non_upper_case_globals)] +#[allow(unused_assignments)] +mod celt { + pub mod bands; + pub mod celt; + pub mod celt_decoder; + pub mod celt_encoder; + pub mod celt_lpc; + pub mod cwrs; + pub mod entcode; + pub mod entdec; + pub mod entenc; + pub mod kiss_fft; + pub mod laplace; + pub mod mathops; + pub mod mdct; + pub mod modes; + pub mod pitch; + pub mod quant_bands; + pub mod rate; + // pub mod tests { + // pub mod test_unit_cwrs32; + // pub mod test_unit_dft; + // pub mod test_unit_entropy; + // pub mod test_unit_laplace; + // pub mod test_unit_mathops; + // pub mod test_unit_mdct; + // pub mod test_unit_rotation; + // pub mod test_unit_types; + // } // mod tests + pub mod vq; + // stuff for structs that do not have a clear home, named after the header files + pub mod float_cast; +} // mod celt + +#[allow(non_camel_case_types)] +#[allow(non_snake_case)] +#[allow(non_upper_case_globals)] +#[allow(unused_assignments)] +mod silk { + pub mod A2NLSF; + pub mod CNG; + pub mod HP_variable_cutoff; + pub mod LPC_analysis_filter; + pub mod LPC_fit; + pub mod LPC_inv_pred_gain; + pub mod LP_variable_cutoff; + pub mod NLSF2A; + pub mod NLSF_VQ; + pub mod NLSF_VQ_weights_laroia; + pub mod NLSF_decode; + pub mod NLSF_del_dec_quant; + pub mod NLSF_encode; + pub mod NLSF_stabilize; + pub mod NLSF_unpack; + pub mod NSQ; + pub mod NSQ_del_dec; + pub mod PLC; + pub mod VAD; + pub mod VQ_WMat_EC; + pub mod ana_filt_bank_1; + pub mod biquad_alt; + pub mod bwexpander; + pub mod bwexpander_32; + pub mod check_control_input; + pub mod code_signs; + pub mod control_SNR; + pub mod control_audio_bandwidth; + pub mod control_codec; + pub mod debug; + pub mod dec_API; + pub mod decode_core; + pub mod decode_frame; + pub mod decode_indices; + pub mod decode_parameters; + pub mod decode_pitch; + pub mod decode_pulses; + pub mod decoder_set_fs; + pub mod enc_API; + pub mod encode_indices; + pub mod encode_pulses; + pub mod float { + pub mod LPC_analysis_filter_FLP; + pub mod LTP_analysis_filter_FLP; + pub mod LTP_scale_ctrl_FLP; + pub mod apply_sine_window_FLP; + pub mod autocorrelation_FLP; + pub mod burg_modified_FLP; + pub mod bwexpander_FLP; + pub mod corrMatrix_FLP; + pub mod encode_frame_FLP; + pub mod energy_FLP; + pub mod find_LPC_FLP; + pub mod find_LTP_FLP; + pub mod find_pitch_lags_FLP; + pub mod find_pred_coefs_FLP; + pub mod inner_product_FLP; + pub mod k2a_FLP; + pub mod noise_shape_analysis_FLP; + pub mod pitch_analysis_core_FLP; + pub mod process_gains_FLP; + pub mod residual_energy_FLP; + pub mod scale_copy_vector_FLP; + pub mod scale_vector_FLP; + pub mod schur_FLP; + pub mod sort_FLP; + pub mod structs_FLP; + pub mod warped_autocorrelation_FLP; + pub mod wrappers_FLP; + } // mod float + pub mod gain_quant; + pub mod init_decoder; + pub mod init_encoder; + pub mod inner_prod_aligned; + pub mod interpolate; + pub mod lin2log; + pub mod log2lin; + pub mod pitch_est_tables; + pub mod process_NLSFs; + pub mod quant_LTP_gains; + pub mod resampler; + pub mod shell_coder; + pub mod sigm_Q15; + pub mod sort; + pub mod stereo_LR_to_MS; + pub mod stereo_MS_to_LR; + pub mod stereo_decode_pred; + pub mod stereo_encode_pred; + pub mod stereo_find_predictor; + pub mod stereo_quant_pred; + pub mod sum_sqr_shift; + pub mod table_LSF_cos; + pub mod tables_LTP; + pub mod tables_NLSF_CB_NB_MB; + pub mod tables_NLSF_CB_WB; + pub mod tables_gain; + pub mod tables_other; + pub mod tables_pitch_lag; + pub mod tables_pulses_per_block; + // stuff for structs that do not have a clear home, named after the header files + pub mod Inlines; + pub mod SigProc_FIX; + pub mod define; + pub mod macros; + pub mod structs; + + pub mod mathops; +} // mod silk + +#[allow(non_camel_case_types)] +#[allow(non_snake_case)] +#[allow(non_upper_case_globals)] +#[allow(unused_assignments)] +mod src { + pub mod analysis; + pub mod mapping_matrix; + pub mod mlp; + pub mod mlp_data; + pub mod opus; + pub mod opus_decoder; + pub mod opus_encoder; + pub mod opus_multistream; + pub mod opus_multistream_decoder; + pub mod opus_multistream_encoder; + pub mod opus_projection_decoder; + pub mod opus_projection_encoder; + pub mod repacketizer; + // stuff for structs that do not have a clear home, named after the header files + pub mod opus_defines; + pub mod opus_private; +} // mod src + +// TODO: copy over the docs +// ===== +// opus.h +// ===== + +// opus_encoder +pub use crate::src::opus_encoder::{ + opus_encode, opus_encode_float, opus_encoder_create, opus_encoder_ctl_impl, + opus_encoder_destroy, opus_encoder_get_size, opus_encoder_init, OpusEncoder, +}; +// opus_decoder +pub use crate::src::opus_decoder::{ + opus_decode, opus_decode_float, opus_decoder_create, opus_decoder_ctl_impl, + opus_decoder_destroy, opus_decoder_get_nb_samples, opus_decoder_get_size, opus_decoder_init, + opus_packet_get_bandwidth, opus_packet_get_nb_channels, opus_packet_get_nb_frames, + opus_packet_get_nb_samples, OpusDecoder, +}; + +pub use crate::src::opus::{ + opus_packet_get_samples_per_frame, opus_packet_parse, opus_pcm_soft_clip, +}; +// opus_repacketizer +pub use crate::src::repacketizer::{ + opus_multistream_packet_pad, opus_multistream_packet_unpad, opus_packet_pad, opus_packet_unpad, + opus_repacketizer_cat, opus_repacketizer_create, opus_repacketizer_destroy, + opus_repacketizer_get_nb_frames, opus_repacketizer_get_size, opus_repacketizer_init, + opus_repacketizer_out, opus_repacketizer_out_range, opus_repacketizer_out_range_impl, + OpusRepacketizer, +}; + +// ===== +// opus_defines.h +// ===== +// opus_errorcodes +pub use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_BUFFER_TOO_SMALL, OPUS_INTERNAL_ERROR, OPUS_INVALID_PACKET, + OPUS_INVALID_STATE, OPUS_OK, OPUS_UNIMPLEMENTED, +}; +pub use crate::src::opus_defines::{ + OPUS_GET_APPLICATION_REQUEST, OPUS_GET_BANDWIDTH_REQUEST, OPUS_GET_BITRATE_REQUEST, + OPUS_GET_COMPLEXITY_REQUEST, OPUS_GET_DTX_REQUEST, OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, + OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_FORCE_CHANNELS_REQUEST, OPUS_GET_GAIN_REQUEST, + OPUS_GET_INBAND_FEC_REQUEST, OPUS_GET_IN_DTX_REQUEST, OPUS_GET_LAST_PACKET_DURATION_REQUEST, + OPUS_GET_LOOKAHEAD_REQUEST, OPUS_GET_LSB_DEPTH_REQUEST, OPUS_GET_MAX_BANDWIDTH_REQUEST, + OPUS_GET_PACKET_LOSS_PERC_REQUEST, OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, + OPUS_GET_PITCH_REQUEST, OPUS_GET_PREDICTION_DISABLED_REQUEST, OPUS_GET_SAMPLE_RATE_REQUEST, + OPUS_GET_SIGNAL_REQUEST, OPUS_GET_VBR_CONSTRAINT_REQUEST, OPUS_GET_VBR_REQUEST, + OPUS_RESET_STATE, OPUS_SET_APPLICATION_REQUEST, OPUS_SET_BANDWIDTH_REQUEST, + OPUS_SET_BITRATE_REQUEST, OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST, + OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, OPUS_SET_FORCE_CHANNELS_REQUEST, OPUS_SET_GAIN_REQUEST, + OPUS_SET_INBAND_FEC_REQUEST, OPUS_SET_LSB_DEPTH_REQUEST, OPUS_SET_MAX_BANDWIDTH_REQUEST, + OPUS_SET_PACKET_LOSS_PERC_REQUEST, OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, + OPUS_SET_PREDICTION_DISABLED_REQUEST, OPUS_SET_SIGNAL_REQUEST, OPUS_SET_VBR_CONSTRAINT_REQUEST, + OPUS_SET_VBR_REQUEST, +}; +// opus_ctlvalues +pub use crate::src::opus_defines::{ + OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_RESTRICTED_LOWDELAY, OPUS_APPLICATION_VOIP, OPUS_AUTO, + OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_NARROWBAND, + OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_WIDEBAND, OPUS_BITRATE_MAX, OPUS_FRAMESIZE_100_MS, + OPUS_FRAMESIZE_10_MS, OPUS_FRAMESIZE_120_MS, OPUS_FRAMESIZE_20_MS, OPUS_FRAMESIZE_2_5_MS, + OPUS_FRAMESIZE_40_MS, OPUS_FRAMESIZE_5_MS, OPUS_FRAMESIZE_60_MS, OPUS_FRAMESIZE_80_MS, + OPUS_FRAMESIZE_ARG, OPUS_SIGNAL_MUSIC, OPUS_SIGNAL_VOICE, +}; +// opus_libinfo +pub use crate::celt::celt::{opus_get_version_string, opus_strerror}; + +// ===== +// opus_multistream.h +// ===== +pub use crate::src::opus_multistream_decoder::{ + opus_multistream_decode, opus_multistream_decode_float, opus_multistream_decoder_create, + opus_multistream_decoder_ctl_impl, opus_multistream_decoder_destroy, + opus_multistream_decoder_get_size, opus_multistream_decoder_init, OpusMSDecoder, +}; +pub use crate::src::opus_multistream_encoder::{ + opus_multistream_encode, opus_multistream_encode_float, opus_multistream_encoder_create, + opus_multistream_encoder_ctl_impl, opus_multistream_encoder_destroy, + opus_multistream_encoder_get_size, opus_multistream_encoder_init, + opus_multistream_surround_encoder_create, opus_multistream_surround_encoder_get_size, + opus_multistream_surround_encoder_init, OpusMSEncoder, +}; + +// ===== +// opus_projection.h +// ===== +pub use crate::src::opus_projection_decoder::{ + opus_projection_decode, opus_projection_decode_float, opus_projection_decoder_create, + opus_projection_decoder_ctl_impl, opus_projection_decoder_destroy, + opus_projection_decoder_get_size, opus_projection_decoder_init, OpusProjectionDecoder, +}; +pub use crate::src::opus_projection_encoder::{ + opus_projection_ambisonics_encoder_create, opus_projection_ambisonics_encoder_get_size, + opus_projection_ambisonics_encoder_init, opus_projection_encode, opus_projection_encode_float, + opus_projection_encoder_ctl_impl, opus_projection_encoder_destroy, OpusProjectionEncoder, +}; + +// ===== +// opus_custom.h +// ===== +pub use crate::celt::celt_decoder::{opus_custom_decoder_ctl_impl, OpusCustomDecoder}; +pub use crate::celt::celt_encoder::{opus_custom_encoder_ctl_impl, OpusCustomEncoder}; +// NOTE: we don't support opus custom modes, so no opus_custom_destroy here +pub use crate::celt::modes::{opus_custom_mode_create, OpusCustomMode}; + +// expose opus_private +pub use crate::src::opus_private; diff --git a/vendor/unsafe-libopus/src/silk/A2NLSF.rs b/vendor/unsafe-libopus/src/silk/A2NLSF.rs new file mode 100644 index 00000000..5f49d04a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/A2NLSF.rs @@ -0,0 +1,198 @@ +use crate::silk::bwexpander_32::silk_bwexpander_32; +use crate::silk::SigProc_FIX::silk_min_32; + +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +pub use self::typedef_h::silk_int16_MAX; +use crate::silk::define::LSF_COS_TAB_SZ_FIX; +use crate::silk::table_LSF_cos::silk_LSFCosTab_FIX_Q12; + +pub const BIN_DIV_STEPS_A2NLSF_FIX: i32 = 3; +pub const MAX_ITERATIONS_A2NLSF_FIX: i32 = 16; +#[inline] +unsafe fn silk_A2NLSF_trans_poly(p: *mut i32, dd: i32) { + let mut k: i32 = 0; + let mut n: i32 = 0; + k = 2; + while k <= dd { + n = dd; + while n > k { + let ref mut fresh0 = *p.offset((n - 2) as isize); + *fresh0 -= *p.offset(n as isize); + n -= 1; + } + let ref mut fresh1 = *p.offset((k - 2) as isize); + *fresh1 -= ((*p.offset(k as isize) as u32) << 1) as i32; + k += 1; + } +} +#[inline] +unsafe fn silk_A2NLSF_eval_poly(p: *mut i32, x: i32, dd: i32) -> i32 { + let mut n: i32 = 0; + let mut x_Q16: i32 = 0; + let mut y32: i32 = 0; + y32 = *p.offset(dd as isize); + x_Q16 = ((x as u32) << 4) as i32; + if (8 == dd) as i32 as i64 != 0 { + y32 = (*p.offset(7 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(6 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(5 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(4 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(3 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(2 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(1 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + y32 = (*p.offset(0 as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + } else { + n = dd - 1; + while n >= 0 { + y32 = (*p.offset(n as isize) as i64 + (y32 as i64 * x_Q16 as i64 >> 16)) as i32; + n -= 1; + } + } + return y32; +} +#[inline] +unsafe fn silk_A2NLSF_init(a_Q16: *const i32, P: *mut i32, Q: *mut i32, dd: i32) { + let mut k: i32 = 0; + *P.offset(dd as isize) = ((1) << 16) as i32; + *Q.offset(dd as isize) = ((1) << 16) as i32; + k = 0; + while k < dd { + *P.offset(k as isize) = + -*a_Q16.offset((dd - k - 1) as isize) - *a_Q16.offset((dd + k) as isize); + *Q.offset(k as isize) = + -*a_Q16.offset((dd - k - 1) as isize) + *a_Q16.offset((dd + k) as isize); + k += 1; + } + k = dd; + while k > 0 { + let ref mut fresh2 = *P.offset((k - 1) as isize); + *fresh2 -= *P.offset(k as isize); + let ref mut fresh3 = *Q.offset((k - 1) as isize); + *fresh3 += *Q.offset(k as isize); + k -= 1; + } + silk_A2NLSF_trans_poly(P, dd); + silk_A2NLSF_trans_poly(Q, dd); +} +pub unsafe fn silk_A2NLSF(NLSF: *mut i16, a_Q16: *mut i32, d: i32) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut m: i32 = 0; + let mut dd: i32 = 0; + let mut root_ix: i32 = 0; + let mut ffrac: i32 = 0; + let mut xlo: i32 = 0; + let mut xhi: i32 = 0; + let mut xmid: i32 = 0; + let mut ylo: i32 = 0; + let mut yhi: i32 = 0; + let mut ymid: i32 = 0; + let mut thr: i32 = 0; + let mut nom: i32 = 0; + let mut den: i32 = 0; + let mut P: [i32; 13] = [0; 13]; + let mut Q: [i32; 13] = [0; 13]; + let mut PQ: [*mut i32; 2] = [0 as *mut i32; 2]; + let mut p: *mut i32 = 0 as *mut i32; + PQ[0 as usize] = P.as_mut_ptr(); + PQ[1 as usize] = Q.as_mut_ptr(); + dd = d >> 1; + silk_A2NLSF_init(a_Q16, P.as_mut_ptr(), Q.as_mut_ptr(), dd); + p = P.as_mut_ptr(); + xlo = silk_LSFCosTab_FIX_Q12[0 as usize] as i32; + ylo = silk_A2NLSF_eval_poly(p, xlo, dd); + if ylo < 0 { + *NLSF.offset(0 as isize) = 0; + p = Q.as_mut_ptr(); + ylo = silk_A2NLSF_eval_poly(p, xlo, dd); + root_ix = 1; + } else { + root_ix = 0; + } + k = 1; + i = 0; + thr = 0; + loop { + xhi = silk_LSFCosTab_FIX_Q12[k as usize] as i32; + yhi = silk_A2NLSF_eval_poly(p, xhi, dd); + if ylo <= 0 && yhi >= thr || ylo >= 0 && yhi <= -thr { + if yhi == 0 { + thr = 1; + } else { + thr = 0; + } + ffrac = -(256); + m = 0; + while m < BIN_DIV_STEPS_A2NLSF_FIX { + xmid = if 1 == 1 { + (xlo + xhi >> 1) + (xlo + xhi & 1) + } else { + (xlo + xhi >> 1 - 1) + 1 >> 1 + }; + ymid = silk_A2NLSF_eval_poly(p, xmid, dd); + if ylo <= 0 && ymid >= 0 || ylo >= 0 && ymid <= 0 { + xhi = xmid; + yhi = ymid; + } else { + xlo = xmid; + ylo = ymid; + ffrac = ffrac + (128 >> m); + } + m += 1; + } + if (if ylo > 0 { ylo } else { -ylo }) < 65536 { + den = ylo - yhi; + nom = ((ylo as u32) << 8 - 3) as i32 + (den >> 1); + if den != 0 { + ffrac += nom / den; + } + } else { + ffrac += ylo / (ylo - yhi >> 8 - 3); + } + *NLSF.offset(root_ix as isize) = + silk_min_32(((k as u32) << 8) as i32 + ffrac, silk_int16_MAX) as i16; + root_ix += 1; + if root_ix >= d { + break; + } + p = PQ[(root_ix & 1) as usize]; + xlo = silk_LSFCosTab_FIX_Q12[(k - 1) as usize] as i32; + ylo = (((1 - (root_ix & 2)) as u32) << 12) as i32; + } else { + k += 1; + xlo = xhi; + ylo = yhi; + thr = 0; + if k > LSF_COS_TAB_SZ_FIX { + i += 1; + if i > MAX_ITERATIONS_A2NLSF_FIX { + *NLSF.offset(0 as isize) = (((1) << 15) / (d + 1)) as i16; + k = 1; + while k < d { + *NLSF.offset(k as isize) = (*NLSF.offset((k - 1) as isize) as i32 + + *NLSF.offset(0 as isize) as i32) + as i16; + k += 1; + } + return; + } + silk_bwexpander_32(a_Q16, d, 65536 - ((1) << i) as i32); + silk_A2NLSF_init(a_Q16, P.as_mut_ptr(), Q.as_mut_ptr(), dd); + p = P.as_mut_ptr(); + xlo = silk_LSFCosTab_FIX_Q12[0 as usize] as i32; + ylo = silk_A2NLSF_eval_poly(p, xlo, dd); + if ylo < 0 { + *NLSF.offset(0 as isize) = 0; + p = Q.as_mut_ptr(); + ylo = silk_A2NLSF_eval_poly(p, xlo, dd); + root_ix = 1; + } else { + root_ix = 0; + } + k = 1; + } + } + } +} diff --git a/vendor/unsafe-libopus/src/silk/CNG.rs b/vendor/unsafe-libopus/src/silk/CNG.rs new file mode 100644 index 00000000..5b44245b --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/CNG.rs @@ -0,0 +1,550 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int32_MAX: i32 = i32::MAX; + pub const silk_int32_MIN: i32 = i32::MIN; +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN, silk_int32_MAX, silk_int32_MIN}; +use crate::externs::{memcpy, memmove, memset}; +use crate::silk::define::{CNG_BUF_MASK_MAX, MAX_LPC_ORDER, TYPE_NO_VOICE_ACTIVITY}; +use crate::silk::structs::{silk_CNG_struct, silk_decoder_control, silk_decoder_state}; +use crate::silk::Inlines::silk_SQRT_APPROX; +use crate::silk::NLSF2A::silk_NLSF2A; +#[inline] +unsafe fn silk_CNG_exc(exc_Q14: *mut i32, exc_buf_Q14: *mut i32, length: i32, rand_seed: *mut i32) { + let mut seed: i32 = 0; + let mut i: i32 = 0; + let mut idx: i32 = 0; + let mut exc_mask: i32 = 0; + exc_mask = CNG_BUF_MASK_MAX; + while exc_mask > length { + exc_mask = exc_mask >> 1; + } + seed = *rand_seed; + i = 0; + while i < length { + seed = 907633515_u32.wrapping_add((seed as u32).wrapping_mul(196314165)) as i32; + idx = seed >> 24 & exc_mask; + *exc_Q14.offset(i as isize) = *exc_buf_Q14.offset(idx as isize); + i += 1; + } + *rand_seed = seed; +} +pub unsafe fn silk_CNG_Reset(psDec: *mut silk_decoder_state) { + let mut i: i32 = 0; + let mut NLSF_step_Q15: i32 = 0; + let mut NLSF_acc_Q15: i32 = 0; + NLSF_step_Q15 = 0x7fff / ((*psDec).LPC_order + 1); + NLSF_acc_Q15 = 0; + i = 0; + while i < (*psDec).LPC_order { + NLSF_acc_Q15 += NLSF_step_Q15; + (*psDec).sCNG.CNG_smth_NLSF_Q15[i as usize] = NLSF_acc_Q15 as i16; + i += 1; + } + (*psDec).sCNG.CNG_smth_Gain_Q16 = 0; + (*psDec).sCNG.rand_seed = 3176576; +} +pub unsafe fn silk_CNG( + psDec: *mut silk_decoder_state, + psDecCtrl: *mut silk_decoder_control, + frame: *mut i16, + length: i32, +) { + let mut i: i32 = 0; + let mut subfr: i32 = 0; + let mut LPC_pred_Q10: i32 = 0; + let mut max_Gain_Q16: i32 = 0; + let mut gain_Q16: i32 = 0; + let mut gain_Q10: i32 = 0; + let mut A_Q12: [i16; 16] = [0; 16]; + let psCNG: *mut silk_CNG_struct = &mut (*psDec).sCNG; + if (*psDec).fs_kHz != (*psCNG).fs_kHz { + silk_CNG_Reset(psDec); + (*psCNG).fs_kHz = (*psDec).fs_kHz; + } + if (*psDec).lossCnt == 0 && (*psDec).prevSignalType == TYPE_NO_VOICE_ACTIVITY { + i = 0; + while i < (*psDec).LPC_order { + (*psCNG).CNG_smth_NLSF_Q15[i as usize] = ((*psCNG).CNG_smth_NLSF_Q15[i as usize] as i32 + + (((*psDec).prevNLSF_Q15[i as usize] as i32 + - (*psCNG).CNG_smth_NLSF_Q15[i as usize] as i32) as i64 + * 16348 as i64 + >> 16) as i32) as i16; + i += 1; + } + max_Gain_Q16 = 0; + subfr = 0; + i = 0; + while i < (*psDec).nb_subfr { + if (*psDecCtrl).Gains_Q16[i as usize] > max_Gain_Q16 { + max_Gain_Q16 = (*psDecCtrl).Gains_Q16[i as usize]; + subfr = i; + } + i += 1; + } + memmove( + &mut *((*psCNG).CNG_exc_buf_Q14) + .as_mut_ptr() + .offset((*psDec).subfr_length as isize) as *mut i32 + as *mut core::ffi::c_void, + ((*psCNG).CNG_exc_buf_Q14).as_mut_ptr() as *const core::ffi::c_void, + ((((*psDec).nb_subfr - 1) * (*psDec).subfr_length) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*psCNG).CNG_exc_buf_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psDec).exc_Q14) + .as_mut_ptr() + .offset((subfr * (*psDec).subfr_length) as isize) as *mut i32 + as *const core::ffi::c_void, + ((*psDec).subfr_length as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + i = 0; + while i < (*psDec).nb_subfr { + (*psCNG).CNG_smth_Gain_Q16 += (((*psDecCtrl).Gains_Q16[i as usize] + - (*psCNG).CNG_smth_Gain_Q16) as i64 + * 4634 as i64 + >> 16) as i32; + i += 1; + } + } + if (*psDec).lossCnt != 0 { + let vla = (length + 16) as usize; + let mut CNG_sig_Q14: Vec = ::std::vec::from_elem(0, vla); + gain_Q16 = ((*psDec).sPLC.randScale_Q14 as i64 + * (*psDec).sPLC.prevGain_Q16[1 as usize] as i64 + >> 16) as i32; + if gain_Q16 >= (1) << 21 || (*psCNG).CNG_smth_Gain_Q16 > (1) << 23 { + gain_Q16 = (gain_Q16 >> 16) * (gain_Q16 >> 16); + gain_Q16 = ((*psCNG).CNG_smth_Gain_Q16 >> 16) * ((*psCNG).CNG_smth_Gain_Q16 >> 16) + - ((gain_Q16 as u32) << 5) as i32; + gain_Q16 = ((silk_SQRT_APPROX(gain_Q16) as u32) << 16) as i32; + } else { + gain_Q16 = (gain_Q16 as i64 * gain_Q16 as i64 >> 16) as i32; + gain_Q16 = ((*psCNG).CNG_smth_Gain_Q16 as i64 * (*psCNG).CNG_smth_Gain_Q16 as i64 >> 16) + as i32 + - ((gain_Q16 as u32) << 5) as i32; + gain_Q16 = ((silk_SQRT_APPROX(gain_Q16) as u32) << 8) as i32; + } + gain_Q10 = gain_Q16 >> 6; + silk_CNG_exc( + CNG_sig_Q14.as_mut_ptr().offset(MAX_LPC_ORDER as isize), + ((*psCNG).CNG_exc_buf_Q14).as_mut_ptr(), + length, + &mut (*psCNG).rand_seed, + ); + silk_NLSF2A( + A_Q12.as_mut_ptr(), + ((*psCNG).CNG_smth_NLSF_Q15).as_mut_ptr(), + (*psDec).LPC_order, + (*psDec).arch, + ); + memcpy( + CNG_sig_Q14.as_mut_ptr() as *mut core::ffi::c_void, + ((*psCNG).CNG_synth_state).as_mut_ptr() as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + assert!((*psDec).LPC_order == 10 || (*psDec).LPC_order == 16); + i = 0; + while i < length { + LPC_pred_Q10 = (*psDec).LPC_order >> 1; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 1) as isize) as i64 + * A_Q12[0 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 2) as isize) as i64 + * A_Q12[1 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 3) as isize) as i64 + * A_Q12[2 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 4) as isize) as i64 + * A_Q12[3 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 5) as isize) as i64 + * A_Q12[4 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 6) as isize) as i64 + * A_Q12[5 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 7) as isize) as i64 + * A_Q12[6 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 8) as isize) as i64 + * A_Q12[7 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 9) as isize) as i64 + * A_Q12[8 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 10) as isize) as i64 + * A_Q12[9 as usize] as i64 + >> 16)) as i32; + if (*psDec).LPC_order == 16 { + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 11) as isize) as i64 + * A_Q12[10 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 12) as isize) as i64 + * A_Q12[11 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 13) as isize) as i64 + * A_Q12[12 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 14) as isize) as i64 + * A_Q12[13 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 15) as isize) as i64 + * A_Q12[14 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*CNG_sig_Q14.as_mut_ptr().offset((16 + i - 16) as isize) as i64 + * A_Q12[15 as usize] as i64 + >> 16)) as i32; + } + *CNG_sig_Q14 + .as_mut_ptr() + .offset((MAX_LPC_ORDER + i) as isize) = + if (*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as u32).wrapping_add( + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if (*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) + & (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32) as u32 + & 0x80000000 as u32 + != 0 + { + silk_int32_MIN as i32 + } else { + *CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) + + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 + } + } else if (*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) + | (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32) as u32 + & 0x80000000 as u32 + == 0 + { + silk_int32_MAX + } else { + *CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) + + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 + }; + *frame.offset(i as isize) = (if *frame.offset(i as isize) as i32 + + (if (if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > 0x7fff + { + 0x7fff + } else { + if (if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < -0x8000 // tinyclient patch: silk_int16_MIN is -32768, not 0x8000 + { + -0x8000 + } else { + if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + } + } + }) + > silk_int16_MAX + { + silk_int16_MAX + } else if *frame.offset(i as isize) as i32 + + (if (if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > 0x7fff + { + 0x7fff + } else { + if (if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < -0x8000 // tinyclient patch: silk_int16_MIN is -32768, not 0x8000 + { + -0x8000 + } else { + if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + } + } + }) + < silk_int16_MIN + { + silk_int16_MIN + } else { + *frame.offset(i as isize) as i32 + + (if (if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > 0x7fff + { + 0x7fff + } else { + if (if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < -0x8000 // tinyclient patch: silk_int16_MIN is -32768, not 0x8000 + { + -0x8000 + } else { + if 8 == 1 { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 1) + + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*CNG_sig_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 + * gain_Q10 as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + } + } + }) + }) as i16; + i += 1; + } + memcpy( + ((*psCNG).CNG_synth_state).as_mut_ptr() as *mut core::ffi::c_void, + &mut *CNG_sig_Q14.as_mut_ptr().offset(length as isize) as *mut i32 + as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } else { + memset( + ((*psCNG).CNG_synth_state).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ((*psDec).LPC_order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + }; +} diff --git a/vendor/unsafe-libopus/src/silk/HP_variable_cutoff.rs b/vendor/unsafe-libopus/src/silk/HP_variable_cutoff.rs new file mode 100644 index 00000000..aa87fa65 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/HP_variable_cutoff.rs @@ -0,0 +1,67 @@ +use crate::silk::lin2log::silk_lin2log; + +use crate::silk::define::TYPE_VOICED; +use crate::silk::float::structs_FLP::silk_encoder_state_FLP; +use crate::silk::structs::silk_encoder_state; + +pub unsafe fn silk_HP_variable_cutoff(state_Fxx: *mut silk_encoder_state_FLP) { + let mut quality_Q15: i32 = 0; + let mut pitch_freq_Hz_Q16: i32 = 0; + let mut pitch_freq_log_Q7: i32 = 0; + let mut delta_freq_Q7: i32 = 0; + let psEncC1: *mut silk_encoder_state = &mut (*state_Fxx.offset(0 as isize)).sCmn; + if (*psEncC1).prevSignalType as i32 == TYPE_VOICED { + pitch_freq_Hz_Q16 = ((((*psEncC1).fs_kHz * 1000) as u32) << 16) as i32 / (*psEncC1).prevLag; + pitch_freq_log_Q7 = silk_lin2log(pitch_freq_Hz_Q16) - ((16) << 7); + quality_Q15 = (*psEncC1).input_quality_bands_Q15[0 as usize]; + pitch_freq_log_Q7 = (pitch_freq_log_Q7 as i64 + + ((((-quality_Q15 as u32) << 2) as i32 as i64 * quality_Q15 as i16 as i64 >> 16) as i32 + as i64 + * (pitch_freq_log_Q7 + - (silk_lin2log(((60 * ((1) << 16)) as f64 + 0.5f64) as i32) - ((16) << 7))) + as i16 as i64 + >> 16)) as i32; + delta_freq_Q7 = pitch_freq_log_Q7 - ((*psEncC1).variable_HP_smth1_Q15 >> 8); + if delta_freq_Q7 < 0 { + delta_freq_Q7 = delta_freq_Q7 * 3; + } + delta_freq_Q7 = if -(((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32) + > ((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32 + { + if delta_freq_Q7 > -(((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32) { + -(((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32) + } else if delta_freq_Q7 < ((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32 { + ((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32 + } else { + delta_freq_Q7 + } + } else if delta_freq_Q7 > ((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32 { + ((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32 + } else if delta_freq_Q7 < -(((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32) { + -(((0.4f32 * ((1) << 7) as f32) as f64 + 0.5f64) as i32) + } else { + delta_freq_Q7 + }; + (*psEncC1).variable_HP_smth1_Q15 = ((*psEncC1).variable_HP_smth1_Q15 as i64 + + (((*psEncC1).speech_activity_Q8 as i16 as i32 * delta_freq_Q7 as i16 as i32) as i64 + * ((0.1f32 * ((1) << 16) as f32) as f64 + 0.5f64) as i32 as i16 as i64 + >> 16)) as i32; + (*psEncC1).variable_HP_smth1_Q15 = if ((silk_lin2log(60) as u32) << 8) as i32 + > ((silk_lin2log(100) as u32) << 8) as i32 + { + if (*psEncC1).variable_HP_smth1_Q15 > ((silk_lin2log(60) as u32) << 8) as i32 { + ((silk_lin2log(60) as u32) << 8) as i32 + } else if (*psEncC1).variable_HP_smth1_Q15 < ((silk_lin2log(100) as u32) << 8) as i32 { + ((silk_lin2log(100) as u32) << 8) as i32 + } else { + (*psEncC1).variable_HP_smth1_Q15 + } + } else if (*psEncC1).variable_HP_smth1_Q15 > ((silk_lin2log(100) as u32) << 8) as i32 { + ((silk_lin2log(100) as u32) << 8) as i32 + } else if (*psEncC1).variable_HP_smth1_Q15 < ((silk_lin2log(60) as u32) << 8) as i32 { + ((silk_lin2log(60) as u32) << 8) as i32 + } else { + (*psEncC1).variable_HP_smth1_Q15 + }; + } +} diff --git a/vendor/unsafe-libopus/src/silk/Inlines.rs b/vendor/unsafe-libopus/src/silk/Inlines.rs new file mode 100644 index 00000000..5446fecc --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/Inlines.rs @@ -0,0 +1,132 @@ +use crate::silk::macros::silk_CLZ32; +use crate::silk::SigProc_FIX::silk_ROR32; + +/// get number of leading zeros and fractional part (the bits right after the leading one +#[inline] +pub fn silk_CLZ_FRAC(in_0: i32, lz: &mut i32, frac_Q7: &mut i32) { + let lzeros: i32 = silk_CLZ32(in_0); + *lz = lzeros; + *frac_Q7 = silk_ROR32(in_0, 24 - lzeros) & 0x7f; +} + +/// Approximation of square root +/// Accuracy: < +/- 10% for output values > 15 +/// < +/- 2.5% for output values > 120 +#[inline] +pub fn silk_SQRT_APPROX(x: i32) -> i32 { + let mut y: i32 = 0; + let mut lz: i32 = 0; + let mut frac_Q7: i32 = 0; + if x <= 0 { + return 0; + } + silk_CLZ_FRAC(x, &mut lz, &mut frac_Q7); + if lz & 1 != 0 { + y = 32768; + } else { + y = 46214; + } + y >>= lz >> 1; + y = (y as i64 + ((y as i64 * (213 * frac_Q7 as i16 as i32) as i16 as i64) >> 16)) as i32; + return y; +} + +/// Divide two int32 values and return result as int32 in a given Q-domain +#[inline] +pub fn silk_DIV32_varQ(a32: i32, b32: i32, Qres: i32) -> i32 { + let mut a_headrm: i32 = 0; + let mut b_headrm: i32 = 0; + let mut lshift: i32 = 0; + let mut b32_inv: i32 = 0; + let mut a32_nrm: i32 = 0; + let mut b32_nrm: i32 = 0; + let mut result: i32 = 0; + a_headrm = silk_CLZ32(if a32 > 0 { a32 } else { -a32 }) - 1; + a32_nrm = ((a32 as u32) << a_headrm) as i32; + b_headrm = silk_CLZ32(if b32 > 0 { b32 } else { -b32 }) - 1; + b32_nrm = ((b32 as u32) << b_headrm) as i32; + b32_inv = (0x7fffffff >> 2) / (b32_nrm >> 16); + result = (a32_nrm as i64 * b32_inv as i16 as i64 >> 16) as i32; + a32_nrm = (a32_nrm as u32) + .wrapping_sub((((b32_nrm as i64 * result as i64 >> 32) as i32 as u32) << 3) as i32 as u32) + as i32; + result = (result as i64 + (a32_nrm as i64 * b32_inv as i16 as i64 >> 16)) as i32; + lshift = 29 + a_headrm - b_headrm - Qres; + if lshift < 0 { + return (((if 0x80000000 as u32 as i32 >> -lshift > 0x7fffffff >> -lshift { + if result > 0x80000000 as u32 as i32 >> -lshift { + 0x80000000 as u32 as i32 >> -lshift + } else { + if result < 0x7fffffff >> -lshift { + 0x7fffffff >> -lshift + } else { + result + } + } + } else { + if result > 0x7fffffff >> -lshift { + 0x7fffffff >> -lshift + } else { + if result < 0x80000000 as u32 as i32 >> -lshift { + 0x80000000 as u32 as i32 >> -lshift + } else { + result + } + } + }) as u32) + << -lshift) as i32; + } else if lshift < 32 { + return result >> lshift; + } else { + return 0; + }; +} + +/// Invert int32 value and return result as int32 in a given Q-domain +/// +/// returns a good approximation of "(1 << Qres) / b32" +#[inline] +pub fn silk_INVERSE32_varQ(b32: i32, Qres: i32) -> i32 { + let mut b_headrm: i32 = 0; + let mut lshift: i32 = 0; + let mut b32_inv: i32 = 0; + let mut b32_nrm: i32 = 0; + let mut err_Q32: i32 = 0; + let mut result: i32 = 0; + b_headrm = silk_CLZ32(if b32 > 0 { b32 } else { -b32 }) - 1; + b32_nrm = ((b32 as u32) << b_headrm) as i32; + b32_inv = (0x7fffffff >> 2) / (b32_nrm >> 16); + result = ((b32_inv as u32) << 16) as i32; + err_Q32 = (((((1) << 29) - (b32_nrm as i64 * b32_inv as i16 as i64 >> 16) as i32) as u32) << 3) + as i32; + result = (result as i64 + (err_Q32 as i64 * b32_inv as i64 >> 16)) as i32; + lshift = 61 - b_headrm - Qres; + if lshift <= 0 { + return (((if 0x80000000 as u32 as i32 >> -lshift > 0x7fffffff >> -lshift { + if result > 0x80000000 as u32 as i32 >> -lshift { + 0x80000000 as u32 as i32 >> -lshift + } else { + if result < 0x7fffffff >> -lshift { + 0x7fffffff >> -lshift + } else { + result + } + } + } else { + if result > 0x7fffffff >> -lshift { + 0x7fffffff >> -lshift + } else { + if result < 0x80000000 as u32 as i32 >> -lshift { + 0x80000000 as u32 as i32 >> -lshift + } else { + result + } + } + }) as u32) + << -lshift) as i32; + } else if lshift < 32 { + return result >> lshift; + } else { + return 0; + }; +} diff --git a/vendor/unsafe-libopus/src/silk/LPC_analysis_filter.rs b/vendor/unsafe-libopus/src/silk/LPC_analysis_filter.rs new file mode 100644 index 00000000..4f5f6598 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/LPC_analysis_filter.rs @@ -0,0 +1,76 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +use crate::externs::memset; +pub unsafe fn silk_LPC_analysis_filter( + out: *mut i16, + in_0: *const i16, + B: *const i16, + len: i32, + d: i32, + _arch: i32, +) { + let mut j: i32 = 0; + let mut ix: i32 = 0; + let mut out32_Q12: i32 = 0; + let mut out32: i32 = 0; + let mut in_ptr: *const i16 = 0 as *const i16; + assert!(d >= 6); + assert!(d & 1 == 0); + assert!(d <= len); + ix = d; + while ix < len { + in_ptr = &*in_0.offset((ix - 1) as isize) as *const i16; + out32_Q12 = *in_ptr.offset(0 as isize) as i32 * *B.offset(0 as isize) as i32; + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset(-1 as isize) as i32 * *B.offset(1 as isize) as i32) as u32, + ) as i32; + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset(-(2) as isize) as i32 * *B.offset(2 as isize) as i32) as u32, + ) as i32; + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset(-(3) as isize) as i32 * *B.offset(3 as isize) as i32) as u32, + ) as i32; + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset(-(4) as isize) as i32 * *B.offset(4 as isize) as i32) as u32, + ) as i32; + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset(-(5) as isize) as i32 * *B.offset(5 as isize) as i32) as u32, + ) as i32; + j = 6; + while j < d { + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset(-j as isize) as i32 * *B.offset(j as isize) as i32) as u32, + ) as i32; + out32_Q12 = (out32_Q12 as u32).wrapping_add( + (*in_ptr.offset((-j - 1) as isize) as i32 * *B.offset((j + 1) as isize) as i32) + as u32, + ) as i32; + j += 2; + } + out32_Q12 = (((*in_ptr.offset(1 as isize) as i32 as u32) << 12) as i32 as u32) + .wrapping_sub(out32_Q12 as u32) as i32; + out32 = if 12 == 1 { + (out32_Q12 >> 1) + (out32_Q12 & 1) + } else { + (out32_Q12 >> 12 - 1) + 1 >> 1 + }; + *out.offset(ix as isize) = (if out32 > silk_int16_MAX { + silk_int16_MAX + } else if out32 < silk_int16_MIN { + silk_int16_MIN + } else { + out32 + }) as i16; + ix += 1; + } + memset( + out as *mut core::ffi::c_void, + 0, + (d as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); +} diff --git a/vendor/unsafe-libopus/src/silk/LPC_fit.rs b/vendor/unsafe-libopus/src/silk/LPC_fit.rs new file mode 100644 index 00000000..d98a8726 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/LPC_fit.rs @@ -0,0 +1,84 @@ +use crate::silk::bwexpander_32::silk_bwexpander_32; + +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +pub unsafe fn silk_LPC_fit(a_QOUT: *mut i16, a_QIN: *mut i32, QOUT: i32, QIN: i32, d: i32) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut idx: i32 = 0; + let mut maxabs: i32 = 0; + let mut absval: i32 = 0; + let mut chirp_Q16: i32 = 0; + i = 0; + while i < 10 { + maxabs = 0; + k = 0; + while k < d { + absval = if *a_QIN.offset(k as isize) > 0 { + *a_QIN.offset(k as isize) + } else { + -*a_QIN.offset(k as isize) + }; + if absval > maxabs { + maxabs = absval; + idx = k; + } + k += 1; + } + maxabs = if QIN - QOUT == 1 { + (maxabs >> 1) + (maxabs & 1) + } else { + (maxabs >> QIN - QOUT - 1) + 1 >> 1 + }; + if !(maxabs > silk_int16_MAX) { + break; + } + maxabs = if maxabs < 163838 { maxabs } else { 163838 }; + chirp_Q16 = (0.999f64 * ((1) << 16) as f64 + 0.5f64) as i32 + - (((maxabs - 0x7fff) as u32) << 14) as i32 / (maxabs * (idx + 1) >> 2); + silk_bwexpander_32(a_QIN, d, chirp_Q16); + i += 1; + } + if i == 10 { + k = 0; + while k < d { + *a_QOUT.offset(k as isize) = (if (if QIN - QOUT == 1 { + (*a_QIN.offset(k as isize) >> 1) + (*a_QIN.offset(k as isize) & 1) + } else { + (*a_QIN.offset(k as isize) >> QIN - QOUT - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if QIN - QOUT == 1 { + (*a_QIN.offset(k as isize) >> 1) + (*a_QIN.offset(k as isize) & 1) + } else { + (*a_QIN.offset(k as isize) >> QIN - QOUT - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if QIN - QOUT == 1 { + (*a_QIN.offset(k as isize) >> 1) + (*a_QIN.offset(k as isize) & 1) + } else { + (*a_QIN.offset(k as isize) >> QIN - QOUT - 1) + 1 >> 1 + }) as i16; + *a_QIN.offset(k as isize) = + ((*a_QOUT.offset(k as isize) as i32 as u32) << QIN - QOUT) as i32; + k += 1; + } + } else { + k = 0; + while k < d { + *a_QOUT.offset(k as isize) = (if QIN - QOUT == 1 { + (*a_QIN.offset(k as isize) >> 1) + (*a_QIN.offset(k as isize) & 1) + } else { + (*a_QIN.offset(k as isize) >> QIN - QOUT - 1) + 1 >> 1 + }) as i16; + k += 1; + } + }; +} diff --git a/vendor/unsafe-libopus/src/silk/LPC_inv_pred_gain.rs b/vendor/unsafe-libopus/src/silk/LPC_inv_pred_gain.rs new file mode 100644 index 00000000..6a04b9ed --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/LPC_inv_pred_gain.rs @@ -0,0 +1,395 @@ +pub mod typedef_h { + pub const silk_int32_MIN: i32 = i32::MIN; + pub const silk_int32_MAX: i32 = i32::MAX; +} +pub use self::typedef_h::{silk_int32_MAX, silk_int32_MIN}; +use crate::silk::macros::silk_CLZ32; +use crate::silk::Inlines::silk_INVERSE32_varQ; + +pub const A_LIMIT: f64 = 0.99975f64 * ((1) << 24) as f64 + 0.5f64; + +/// Compute inverse of LPC prediction gain, and +/// test if LPC coefficients are stable (all poles within unit circle) +unsafe fn LPC_inverse_pred_gain_QA_c(A_QA: *mut i32, order: i32) -> i32 { + let mut k: i32 = 0; + let mut n: i32 = 0; + let mut mult2Q: i32 = 0; + let mut invGain_Q30: i32 = 0; + let mut rc_Q31: i32 = 0; + let mut rc_mult1_Q30: i32 = 0; + let mut rc_mult2: i32 = 0; + let mut tmp1: i32 = 0; + let mut tmp2: i32 = 0; + invGain_Q30 = ((1 * ((1) << 30)) as f64 + 0.5f64) as i32; + k = order - 1; + while k > 0 { + if *A_QA.offset(k as isize) > A_LIMIT as i32 || *A_QA.offset(k as isize) < -(A_LIMIT as i32) + { + return 0; + } + rc_Q31 = -(((*A_QA.offset(k as isize) as u32) << 31 - 24) as i32); + rc_mult1_Q30 = ((1 * ((1) << 30)) as f64 + 0.5f64) as i32 + - (rc_Q31 as i64 * rc_Q31 as i64 >> 32) as i32; + invGain_Q30 = + (((invGain_Q30 as i64 * rc_mult1_Q30 as i64 >> 32) as i32 as u32) << 2) as i32; + if invGain_Q30 < ((1.0f32 / 1e4f32 * ((1) << 30) as f32) as f64 + 0.5f64) as i32 { + return 0; + } + mult2Q = 32 + - silk_CLZ32(if rc_mult1_Q30 > 0 { + rc_mult1_Q30 + } else { + -rc_mult1_Q30 + }); + rc_mult2 = silk_INVERSE32_varQ(rc_mult1_Q30, mult2Q + 30); + n = 0; + while n < k + 1 >> 1 { + let mut tmp64: i64 = 0; + tmp1 = *A_QA.offset(n as isize); + tmp2 = *A_QA.offset((k - n - 1) as isize); + tmp64 = if mult2Q == 1 { + ((if (tmp1 as u32).wrapping_sub( + (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if tmp1 as u32 + & ((if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + ^ 0x80000000 as u32) + & 0x80000000 as u32 + != 0 + { + 0x80000000 as u32 as i32 + } else { + tmp1 - (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + } else { + if (tmp1 as u32 ^ 0x80000000 as u32) + & (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + & 0x80000000 as u32 + != 0 + { + 0x7fffffff + } else { + tmp1 - (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + }) as i64 + * rc_mult2 as i64 + >> 1) + + ((if (tmp1 as u32).wrapping_sub( + (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if tmp1 as u32 + & ((if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + ^ 0x80000000 as u32) + & 0x80000000 as u32 + != 0 + { + 0x80000000 as u32 as i32 + } else { + tmp1 - (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + } else { + if (tmp1 as u32 ^ 0x80000000 as u32) + & (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + & 0x80000000 as u32 + != 0 + { + 0x7fffffff + } else { + tmp1 - (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + }) as i64 + * rc_mult2 as i64 + & 1) + } else { + ((if (tmp1 as u32).wrapping_sub( + (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if tmp1 as u32 + & ((if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + ^ 0x80000000 as u32) + & 0x80000000 as u32 + != 0 + { + 0x80000000 as u32 as i32 + } else { + tmp1 - (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + } else { + if (tmp1 as u32 ^ 0x80000000 as u32) + & (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + & 0x80000000 as u32 + != 0 + { + 0x7fffffff + } else { + tmp1 - (if 31 == 1 { + (tmp2 as i64 * rc_Q31 as i64 >> 1) + (tmp2 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp2 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + }) as i64 + * rc_mult2 as i64 + >> mult2Q - 1) + + 1 + >> 1 + }; + if tmp64 > silk_int32_MAX as i64 || tmp64 < silk_int32_MIN as i64 { + return 0; + } + *A_QA.offset(n as isize) = tmp64 as i32; + tmp64 = if mult2Q == 1 { + ((if (tmp2 as u32).wrapping_sub( + (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if tmp2 as u32 + & ((if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + ^ 0x80000000 as u32) + & 0x80000000 as u32 + != 0 + { + 0x80000000 as u32 as i32 + } else { + tmp2 - (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + } else { + if (tmp2 as u32 ^ 0x80000000 as u32) + & (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + & 0x80000000 as u32 + != 0 + { + 0x7fffffff + } else { + tmp2 - (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + }) as i64 + * rc_mult2 as i64 + >> 1) + + ((if (tmp2 as u32).wrapping_sub( + (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if tmp2 as u32 + & ((if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + ^ 0x80000000 as u32) + & 0x80000000 as u32 + != 0 + { + 0x80000000 as u32 as i32 + } else { + tmp2 - (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + } else { + if (tmp2 as u32 ^ 0x80000000 as u32) + & (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + & 0x80000000 as u32 + != 0 + { + 0x7fffffff + } else { + tmp2 - (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + }) as i64 + * rc_mult2 as i64 + & 1) + } else { + ((if (tmp2 as u32).wrapping_sub( + (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if tmp2 as u32 + & ((if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + ^ 0x80000000 as u32) + & 0x80000000 as u32 + != 0 + { + 0x80000000 as u32 as i32 + } else { + tmp2 - (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + } else { + if (tmp2 as u32 ^ 0x80000000 as u32) + & (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 as u32 + & 0x80000000 as u32 + != 0 + { + 0x7fffffff + } else { + tmp2 - (if 31 == 1 { + (tmp1 as i64 * rc_Q31 as i64 >> 1) + (tmp1 as i64 * rc_Q31 as i64 & 1) + } else { + (tmp1 as i64 * rc_Q31 as i64 >> 31 - 1) + 1 >> 1 + }) as i32 + } + }) as i64 + * rc_mult2 as i64 + >> mult2Q - 1) + + 1 + >> 1 + }; + if tmp64 > silk_int32_MAX as i64 || tmp64 < silk_int32_MIN as i64 { + return 0; + } + *A_QA.offset((k - n - 1) as isize) = tmp64 as i32; + n += 1; + } + k -= 1; + } + if *A_QA.offset(k as isize) > A_LIMIT as i32 || *A_QA.offset(k as isize) < -(A_LIMIT as i32) { + return 0; + } + rc_Q31 = -(((*A_QA.offset(0 as isize) as u32) << 31 - 24) as i32); + rc_mult1_Q30 = + ((1 * ((1) << 30)) as f64 + 0.5f64) as i32 - (rc_Q31 as i64 * rc_Q31 as i64 >> 32) as i32; + invGain_Q30 = (((invGain_Q30 as i64 * rc_mult1_Q30 as i64 >> 32) as i32 as u32) << 2) as i32; + if invGain_Q30 < ((1.0f32 / 1e4f32 * ((1) << 30) as f32) as f64 + 0.5f64) as i32 { + return 0; + } + return invGain_Q30; +} + +pub unsafe fn silk_LPC_inverse_pred_gain_c(A_Q12: *const i16, order: i32) -> i32 { + let mut k: i32 = 0; + let mut Atmp_QA: [i32; 24] = [0; 24]; + let mut DC_resp: i32 = 0; + k = 0; + while k < order { + DC_resp += *A_Q12.offset(k as isize) as i32; + Atmp_QA[k as usize] = ((*A_Q12.offset(k as isize) as i32 as u32) << 24 - 12) as i32; + k += 1; + } + if DC_resp >= 4096 { + return 0; + } + return LPC_inverse_pred_gain_QA_c(Atmp_QA.as_mut_ptr(), order); +} diff --git a/vendor/unsafe-libopus/src/silk/LP_variable_cutoff.rs b/vendor/unsafe-libopus/src/silk/LP_variable_cutoff.rs new file mode 100644 index 00000000..b12b4174 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/LP_variable_cutoff.rs @@ -0,0 +1,128 @@ +use crate::externs::memcpy; +use crate::silk::biquad_alt::silk_biquad_alt_stride1; +use crate::silk::define::{TRANSITION_INT_NUM, TRANSITION_NA, TRANSITION_NB}; +use crate::silk::structs::silk_LP_state; +use crate::silk::tables_other::{silk_Transition_LP_A_Q28, silk_Transition_LP_B_Q28}; + +#[inline] +unsafe fn silk_LP_interpolate_filter_taps( + B_Q28: *mut i32, + A_Q28: *mut i32, + ind: i32, + fac_Q16: i32, +) { + let mut nb: i32 = 0; + let mut na: i32 = 0; + if ind < TRANSITION_INT_NUM - 1 { + if fac_Q16 > 0 { + if fac_Q16 < 32768 { + nb = 0; + while nb < TRANSITION_NB { + *B_Q28.offset(nb as isize) = (silk_Transition_LP_B_Q28[ind as usize] + [nb as usize] as i64 + + ((silk_Transition_LP_B_Q28[(ind + 1) as usize][nb as usize] + - silk_Transition_LP_B_Q28[ind as usize][nb as usize]) + as i64 + * fac_Q16 as i16 as i64 + >> 16)) as i32; + nb += 1; + } + na = 0; + while na < TRANSITION_NA { + *A_Q28.offset(na as isize) = (silk_Transition_LP_A_Q28[ind as usize] + [na as usize] as i64 + + ((silk_Transition_LP_A_Q28[(ind + 1) as usize][na as usize] + - silk_Transition_LP_A_Q28[ind as usize][na as usize]) + as i64 + * fac_Q16 as i16 as i64 + >> 16)) as i32; + na += 1; + } + } else { + nb = 0; + while nb < TRANSITION_NB { + *B_Q28.offset(nb as isize) = (silk_Transition_LP_B_Q28[(ind + 1) as usize] + [nb as usize] as i64 + + ((silk_Transition_LP_B_Q28[(ind + 1) as usize][nb as usize] + - silk_Transition_LP_B_Q28[ind as usize][nb as usize]) + as i64 + * (fac_Q16 - ((1) << 16)) as i16 as i64 + >> 16)) as i32; + nb += 1; + } + na = 0; + while na < TRANSITION_NA { + *A_Q28.offset(na as isize) = (silk_Transition_LP_A_Q28[(ind + 1) as usize] + [na as usize] as i64 + + ((silk_Transition_LP_A_Q28[(ind + 1) as usize][na as usize] + - silk_Transition_LP_A_Q28[ind as usize][na as usize]) + as i64 + * (fac_Q16 - ((1) << 16)) as i16 as i64 + >> 16)) as i32; + na += 1; + } + } + } else { + memcpy( + B_Q28 as *mut core::ffi::c_void, + (silk_Transition_LP_B_Q28[ind as usize]).as_ptr() as *const core::ffi::c_void, + 3_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + A_Q28 as *mut core::ffi::c_void, + (silk_Transition_LP_A_Q28[ind as usize]).as_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } + } else { + memcpy( + B_Q28 as *mut core::ffi::c_void, + (silk_Transition_LP_B_Q28[(5 - 1) as usize]).as_ptr() as *const core::ffi::c_void, + 3_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + A_Q28 as *mut core::ffi::c_void, + (silk_Transition_LP_A_Q28[(5 - 1) as usize]).as_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + }; +} +pub unsafe fn silk_LP_variable_cutoff( + psLP: *mut silk_LP_state, + frame: *mut i16, + frame_length: i32, +) { + let mut B_Q28: [i32; 3] = [0; 3]; + let mut A_Q28: [i32; 2] = [0; 2]; + let mut fac_Q16: i32 = 0; + let mut ind: i32 = 0; + if (*psLP).mode != 0 { + fac_Q16 = (((5120 / (5 * 4) - (*psLP).transition_frame_no) as u32) << 16 - 6) as i32; + ind = fac_Q16 >> 16; + fac_Q16 -= ((ind as u32) << 16) as i32; + silk_LP_interpolate_filter_taps(B_Q28.as_mut_ptr(), A_Q28.as_mut_ptr(), ind, fac_Q16); + (*psLP).transition_frame_no = if 0 > 5120 / (5 * 4) { + if (*psLP).transition_frame_no + (*psLP).mode > 0 { + 0 + } else if (*psLP).transition_frame_no + (*psLP).mode < 5120 / (5 * 4) { + 5120 / (5 * 4) + } else { + (*psLP).transition_frame_no + (*psLP).mode + } + } else if (*psLP).transition_frame_no + (*psLP).mode > 5120 / (5 * 4) { + 5120 / (5 * 4) + } else if (*psLP).transition_frame_no + (*psLP).mode < 0 { + 0 + } else { + (*psLP).transition_frame_no + (*psLP).mode + }; + silk_biquad_alt_stride1( + frame, + B_Q28.as_mut_ptr(), + A_Q28.as_mut_ptr(), + ((*psLP).In_LP_State).as_mut_ptr(), + frame, + frame_length, + ); + } +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF2A.rs b/vendor/unsafe-libopus/src/silk/NLSF2A.rs new file mode 100644 index 00000000..6c1e3c56 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF2A.rs @@ -0,0 +1,115 @@ +use crate::silk::bwexpander_32::silk_bwexpander_32; +use crate::silk::define::MAX_LPC_STABILIZE_ITERATIONS; +use crate::silk::table_LSF_cos::silk_LSFCosTab_FIX_Q12; +use crate::silk::LPC_fit::silk_LPC_fit; +use crate::silk::LPC_inv_pred_gain::silk_LPC_inverse_pred_gain_c; + +pub const QA: i32 = 16; +#[inline] +unsafe fn silk_NLSF2A_find_poly(out: *mut i32, cLSF: *const i32, dd: i32) { + let mut k: i32 = 0; + let mut n: i32 = 0; + let mut ftmp: i32 = 0; + *out.offset(0 as isize) = ((1) << 16) as i32; + *out.offset(1 as isize) = -*cLSF.offset(0 as isize); + k = 1; + while k < dd { + ftmp = *cLSF.offset((2 * k) as isize); + *out.offset((k + 1) as isize) = ((*out.offset((k - 1) as isize) as u32) << 1) as i32 + - (if 16 == 1 { + (ftmp as i64 * *out.offset(k as isize) as i64 >> 1) + + (ftmp as i64 * *out.offset(k as isize) as i64 & 1) + } else { + (ftmp as i64 * *out.offset(k as isize) as i64 >> 16 - 1) + 1 >> 1 + }) as i32; + n = k; + while n > 1 { + let ref mut fresh0 = *out.offset(n as isize); + *fresh0 += *out.offset((n - 2) as isize) + - (if 16 == 1 { + (ftmp as i64 * *out.offset((n - 1) as isize) as i64 >> 1) + + (ftmp as i64 * *out.offset((n - 1) as isize) as i64 & 1) + } else { + (ftmp as i64 * *out.offset((n - 1) as isize) as i64 >> 16 - 1) + 1 >> 1 + }) as i32; + n -= 1; + } + let ref mut fresh1 = *out.offset(1 as isize); + *fresh1 -= ftmp; + k += 1; + } +} + +// compute whitening filter coefficients from normalized line spectral frequencies +pub unsafe fn silk_NLSF2A(a_Q12: *mut i16, NLSF: *const i16, d: i32, _arch: i32) { + static ordering16: [u8; 16] = [0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1]; + static ordering10: [u8; 10] = [0, 9, 6, 3, 4, 5, 8, 1, 2, 7]; + let mut ordering: *const u8 = 0 as *const u8; + let mut k: i32 = 0; + let mut i: i32 = 0; + let mut dd: i32 = 0; + let mut cos_LSF_QA: [i32; 24] = [0; 24]; + let mut P: [i32; 13] = [0; 13]; + let mut Q: [i32; 13] = [0; 13]; + let mut Ptmp: i32 = 0; + let mut Qtmp: i32 = 0; + let mut f_int: i32 = 0; + let mut f_frac: i32 = 0; + let mut cos_val: i32 = 0; + let mut delta: i32 = 0; + let mut a32_QA1: [i32; 24] = [0; 24]; + assert!(d == 10 || d == 16); + ordering = if d == 16 { + ordering16.as_ptr() + } else { + ordering10.as_ptr() + }; + k = 0; + while k < d { + f_int = *NLSF.offset(k as isize) as i32 >> 15 - 7; + f_frac = *NLSF.offset(k as isize) as i32 - ((f_int as u32) << 15 - 7) as i32; + cos_val = silk_LSFCosTab_FIX_Q12[f_int as usize] as i32; + delta = silk_LSFCosTab_FIX_Q12[(f_int + 1) as usize] as i32 - cos_val; + cos_LSF_QA[*ordering.offset(k as isize) as usize] = if 20 - 16 == 1 { + (((cos_val as u32) << 8) as i32 + delta * f_frac >> 1) + + (((cos_val as u32) << 8) as i32 + delta * f_frac & 1) + } else { + (((cos_val as u32) << 8) as i32 + delta * f_frac >> 20 - 16 - 1) + 1 >> 1 + }; + k += 1; + } + dd = d >> 1; + silk_NLSF2A_find_poly( + P.as_mut_ptr(), + &mut *cos_LSF_QA.as_mut_ptr().offset(0 as isize), + dd, + ); + silk_NLSF2A_find_poly( + Q.as_mut_ptr(), + &mut *cos_LSF_QA.as_mut_ptr().offset(1 as isize), + dd, + ); + k = 0; + while k < dd { + Ptmp = P[(k + 1) as usize] + P[k as usize]; + Qtmp = Q[(k + 1) as usize] - Q[k as usize]; + a32_QA1[k as usize] = -Qtmp - Ptmp; + a32_QA1[(d - k - 1) as usize] = Qtmp - Ptmp; + k += 1; + } + silk_LPC_fit(a_Q12, a32_QA1.as_mut_ptr(), 12, QA + 1, d); + i = 0; + while silk_LPC_inverse_pred_gain_c(a_Q12, d) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS { + silk_bwexpander_32(a32_QA1.as_mut_ptr(), d, 65536 - ((2) << i) as i32); + k = 0; + while k < d { + *a_Q12.offset(k as isize) = (if 16 + 1 - 12 == 1 { + (a32_QA1[k as usize] >> 1) + (a32_QA1[k as usize] & 1) + } else { + (a32_QA1[k as usize] >> 16 + 1 - 12 - 1) + 1 >> 1 + }) as i16; + k += 1; + } + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_VQ.rs b/vendor/unsafe-libopus/src/silk/NLSF_VQ.rs new file mode 100644 index 00000000..443c493a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_VQ.rs @@ -0,0 +1,48 @@ +/// Compute quantization errors for an LPC_order element input vector for a VQ codebook +pub fn silk_NLSF_VQ( + // Quantization errors [K] + err_Q24: &mut [i32], + // Input vectors to be quantized [LPC_order] + in_Q15: &[i16], + // Codebook vectors [K*LPC_order] + pCB_Q8: &[u8], + // Codebook weights [K*LPC_order] + pWght_Q9: &[i16], + // Number of codebook vectors + K: usize, + // Number of LPCs + LPC_order: usize, +) { + assert_eq!(err_Q24.len(), K); + assert_eq!(in_Q15.len(), LPC_order); + assert_eq!(pCB_Q8.len(), K * LPC_order); + assert_eq!(pWght_Q9.len(), K * LPC_order); + + assert_eq!(LPC_order & 1, 0); + + let mut diff_Q15: i32 = 0; + let mut diffw_Q24: i32 = 0; + let mut sum_error_Q24: i32 = 0; + let mut pred_Q24: i32 = 0; + let mut cb_Q8_ptr = pCB_Q8; + let mut w_Q9_ptr = pWght_Q9; + + for i in 0..K { + sum_error_Q24 = 0; + pred_Q24 = 0; + + for m in (0..=LPC_order - 2).rev().step_by(2) { + diff_Q15 = in_Q15[m + 1] as i32 - ((cb_Q8_ptr[m + 1] as i32 as u32) << 7) as i32; + diffw_Q24 = diff_Q15 as i16 as i32 * w_Q9_ptr[m + 1] as i32; + sum_error_Q24 += (diffw_Q24 - (pred_Q24 >> 1)).abs(); + pred_Q24 = diffw_Q24; + diff_Q15 = in_Q15[m] as i32 - ((cb_Q8_ptr[m] as i32 as u32) << 7) as i32; + diffw_Q24 = diff_Q15 as i16 as i32 * w_Q9_ptr[m] as i32; + sum_error_Q24 += (diffw_Q24 - (pred_Q24 >> 1)).abs(); + pred_Q24 = diffw_Q24; + } + err_Q24[i] = sum_error_Q24; + cb_Q8_ptr = &cb_Q8_ptr[LPC_order..]; + w_Q9_ptr = &w_Q9_ptr[LPC_order..]; + } +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_VQ_weights_laroia.rs b/vendor/unsafe-libopus/src/silk/NLSF_VQ_weights_laroia.rs new file mode 100644 index 00000000..dabc8776 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_VQ_weights_laroia.rs @@ -0,0 +1,47 @@ +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +pub use self::typedef_h::silk_int16_MAX; +use crate::silk::SigProc_FIX::{silk_max_int, silk_min_int}; + +const NLSF_W_Q: i32 = 2; + +/// Laroia low complexity NLSF weights +/// +/// R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP +/// Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech, +/// Signal Processing, pp. 641-644, 1991. +pub fn silk_NLSF_VQ_weights_laroia(pNLSFW_Q_OUT: &mut [i16], pNLSF_Q15: &[i16]) { + let mut tmp1_int: i32 = 0; + let mut tmp2_int: i32 = 0; + + assert_eq!(pNLSF_Q15.len(), pNLSFW_Q_OUT.len()); + let D = pNLSF_Q15.len(); + + assert!(D > 0); + assert_eq!(D & 1, 0); + + // First value + tmp1_int = silk_max_int(pNLSF_Q15[0] as i32, 1); + tmp1_int = (1 << (15 + NLSF_W_Q)) / tmp1_int; + tmp2_int = silk_max_int(pNLSF_Q15[1] as i32 - pNLSF_Q15[0] as i32, 1); + tmp2_int = (1 << (15 + NLSF_W_Q)) / tmp2_int; + pNLSFW_Q_OUT[0] = silk_min_int(tmp1_int + tmp2_int, silk_int16_MAX) as i16; + + // Main loop + let mut k = 1; + while k < D - 1 { + tmp1_int = silk_max_int(pNLSF_Q15[k + 1] as i32 - pNLSF_Q15[k] as i32, 1); + tmp1_int = (1 << (15 + NLSF_W_Q)) / tmp1_int; + pNLSFW_Q_OUT[k] = silk_min_int(tmp1_int + tmp2_int, silk_int16_MAX) as i16; + tmp2_int = silk_max_int(pNLSF_Q15[k + 2] as i32 - pNLSF_Q15[k + 1] as i32, 1); + tmp2_int = (1 << (15 + NLSF_W_Q)) / tmp2_int; + pNLSFW_Q_OUT[k + 1] = silk_min_int(tmp1_int + tmp2_int, silk_int16_MAX) as i16; + k += 2; + } + + // Last value + tmp1_int = silk_max_int((1 << 15) - pNLSF_Q15[D - 1] as i32, 1); + tmp1_int = (1 << (15 + NLSF_W_Q)) / tmp1_int; + pNLSFW_Q_OUT[D - 1] = silk_min_int(tmp1_int + tmp2_int, silk_int16_MAX) as i16; +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_decode.rs b/vendor/unsafe-libopus/src/silk/NLSF_decode.rs new file mode 100644 index 00000000..038e5d5a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_decode.rs @@ -0,0 +1,92 @@ +use crate::silk::NLSF_stabilize::silk_NLSF_stabilize; +use crate::silk::NLSF_unpack::silk_NLSF_unpack; + +use crate::silk::structs::silk_NLSF_CB_struct; + +/// Predictive dequantizer for NLSF residuals +/// +/// Returns RD value in Q30 +#[inline] +fn silk_NLSF_residual_dequant( + x_Q10: &mut [i16], + indices: &[i8], + pred_coef_Q8: &[u8], + quant_step_size_Q16: i32, +) { + assert_eq!(x_Q10.len(), indices.len()); + assert_eq!(x_Q10.len(), pred_coef_Q8.len()); + + let mut out_Q10 = 0; + + for (x_Q10, (&index, &pref_coef_Q8)) in x_Q10 + .iter_mut() + .zip(indices.iter().zip(pred_coef_Q8.iter())) + .rev() + { + let pred_Q10 = out_Q10 as i16 as i32 * pref_coef_Q8 as i16 as i32 >> 8; + out_Q10 = ((index as u32) << 10) as i32; + if out_Q10 > 0 { + out_Q10 -= (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32; + } else if out_Q10 < 0 { + out_Q10 += (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32; + } + out_Q10 = + (pred_Q10 as i64 + (out_Q10 as i64 * quant_step_size_Q16 as i16 as i64 >> 16)) as i32; + *x_Q10 = out_Q10 as i16; + } +} + +/// NLSF vector decoder +pub fn silk_NLSF_decode( + pNLSF_Q15: &mut [i16], + NLSFIndices: &[i8], + psNLSF_CB: &silk_NLSF_CB_struct, +) { + assert_eq!(pNLSF_Q15.len(), psNLSF_CB.order as usize); + assert_eq!(NLSFIndices.len(), 1 + psNLSF_CB.order as usize); + + let mut pred_Q8: [u8; 16] = [0; 16]; + let mut ec_ix: [i16; 16] = [0; 16]; + let mut res_Q10: [i16; 16] = [0; 16]; + let mut NLSF_Q15_tmp: i32 = 0; + + // Unpack entropy table indices and predictor for current CB1 index + silk_NLSF_unpack(&mut ec_ix, &mut pred_Q8, psNLSF_CB, NLSFIndices[0] as i32); + + // Predictive residual dequantizer + silk_NLSF_residual_dequant( + &mut res_Q10[..psNLSF_CB.order as usize], + &NLSFIndices[1..], + &pred_Q8[..psNLSF_CB.order as usize], + psNLSF_CB.quantStepSize_Q16 as i32, + ); + + // Apply inverse square-rooted weights to first stage and add to output + let pCB_element = + &psNLSF_CB.CB1_NLSF_Q8[(NLSFIndices[0] as i32 * psNLSF_CB.order as i32) as usize..]; + let pCB_Wght_Q9 = + &psNLSF_CB.CB1_Wght_Q9[(NLSFIndices[0] as i32 * psNLSF_CB.order as i32) as usize..]; + for (out, ((&res_Q10, &pCB_Wght_Q9), &pCB_element)) in pNLSF_Q15 + .iter_mut() + .zip(res_Q10.iter().zip(pCB_Wght_Q9).zip(pCB_element)) + { + NLSF_Q15_tmp = ((res_Q10 as i32 as u32) << 14) as i32 / pCB_Wght_Q9 as i32 + + ((pCB_element as i16 as u32) << 7) as i32; + *out = (if 0 > 32767 { + if NLSF_Q15_tmp > 0 { + 0 + } else if NLSF_Q15_tmp < 32767 { + 32767 + } else { + NLSF_Q15_tmp + } + } else if NLSF_Q15_tmp > 32767 { + 32767 + } else if NLSF_Q15_tmp < 0 { + 0 + } else { + NLSF_Q15_tmp + }) as i16; + } + silk_NLSF_stabilize(pNLSF_Q15, psNLSF_CB.deltaMin_Q15); +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_del_dec_quant.rs b/vendor/unsafe-libopus/src/silk/NLSF_del_dec_quant.rs new file mode 100644 index 00000000..ca63c614 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_del_dec_quant.rs @@ -0,0 +1,238 @@ +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; +} +use crate::silk::define::{ + NLSF_QUANT_DEL_DEC_STATES, NLSF_QUANT_MAX_AMPLITUDE, NLSF_QUANT_MAX_AMPLITUDE_EXT, +}; + +pub use self::typedef_h::silk_int32_MAX; + +use crate::externs::memcpy; +pub unsafe fn silk_NLSF_del_dec_quant( + indices: *mut i8, + x_Q10: *const i16, + w_Q5: *const i16, + pred_coef_Q8: *const u8, + ec_ix: *const i16, + ec_rates_Q5: &[u8], + quant_step_size_Q16: i32, + inv_quant_step_size_Q6: i16, + mu_Q20: i32, + order: i16, +) -> i32 { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut nStates: i32 = 0; + let mut ind_tmp: i32 = 0; + let mut ind_min_max: i32 = 0; + let mut ind_max_min: i32 = 0; + let mut in_Q10: i32 = 0; + let mut res_Q10: i32 = 0; + let mut pred_Q10: i32 = 0; + let mut diff_Q10: i32 = 0; + let mut rate0_Q5: i32 = 0; + let mut rate1_Q5: i32 = 0; + let mut out0_Q10: i16 = 0; + let mut out1_Q10: i16 = 0; + let mut RD_tmp_Q25: i32 = 0; + let mut min_Q25: i32 = 0; + let mut min_max_Q25: i32 = 0; + let mut max_min_Q25: i32 = 0; + let mut ind_sort: [i32; 4] = [0; 4]; + let mut ind: [[i8; 16]; 4] = [[0; 16]; 4]; + let mut prev_out_Q10: [i16; 8] = [0; 8]; + let mut RD_Q25: [i32; 8] = [0; 8]; + let mut RD_min_Q25: [i32; 4] = [0; 4]; + let mut RD_max_Q25: [i32; 4] = [0; 4]; + let mut rates_Q5: *const u8 = 0 as *const u8; + let mut out0_Q10_table: [i32; 20] = [0; 20]; + let mut out1_Q10_table: [i32; 20] = [0; 20]; + i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; + while i <= NLSF_QUANT_MAX_AMPLITUDE_EXT - 1 { + out0_Q10 = ((i as u32) << 10) as i32 as i16; + out1_Q10 = (out0_Q10 as i32 + 1024) as i16; + if i > 0 { + out0_Q10 = (out0_Q10 as i32 - (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32) as i16; + out1_Q10 = (out1_Q10 as i32 - (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32) as i16; + } else if i == 0 { + out1_Q10 = (out1_Q10 as i32 - (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32) as i16; + } else if i == -1 { + out0_Q10 = (out0_Q10 as i32 + (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32) as i16; + } else { + out0_Q10 = (out0_Q10 as i32 + (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32) as i16; + out1_Q10 = (out1_Q10 as i32 + (0.1f64 * ((1) << 10) as f64 + 0.5f64) as i32) as i16; + } + out0_Q10_table[(i + NLSF_QUANT_MAX_AMPLITUDE_EXT) as usize] = + out0_Q10 as i32 * quant_step_size_Q16 as i16 as i32 >> 16; + out1_Q10_table[(i + NLSF_QUANT_MAX_AMPLITUDE_EXT) as usize] = + out1_Q10 as i32 * quant_step_size_Q16 as i16 as i32 >> 16; + i += 1; + } + nStates = 1; + RD_Q25[0 as usize] = 0; + prev_out_Q10[0 as usize] = 0; + i = order as i32 - 1; + while i >= 0 { + rates_Q5 = &*ec_rates_Q5 + .as_ptr() + .offset(*ec_ix.offset(i as isize) as isize) as *const u8; + in_Q10 = *x_Q10.offset(i as isize) as i32; + j = 0; + while j < nStates { + pred_Q10 = *pred_coef_Q8.offset(i as isize) as i16 as i32 + * prev_out_Q10[j as usize] as i32 + >> 8; + res_Q10 = in_Q10 - pred_Q10; + ind_tmp = inv_quant_step_size_Q6 as i32 * res_Q10 as i16 as i32 >> 16; + ind_tmp = if -(10) > 10 - 1 { + if ind_tmp > -(10) { + -(10) + } else if ind_tmp < 10 - 1 { + 10 - 1 + } else { + ind_tmp + } + } else if ind_tmp > 10 - 1 { + 10 - 1 + } else if ind_tmp < -(10) { + -(10) + } else { + ind_tmp + }; + ind[j as usize][i as usize] = ind_tmp as i8; + out0_Q10 = out0_Q10_table[(ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT) as usize] as i16; + out1_Q10 = out1_Q10_table[(ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT) as usize] as i16; + out0_Q10 = (out0_Q10 as i32 + pred_Q10) as i16; + out1_Q10 = (out1_Q10 as i32 + pred_Q10) as i16; + prev_out_Q10[j as usize] = out0_Q10; + prev_out_Q10[(j + nStates) as usize] = out1_Q10; + if ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE { + if ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE { + rate0_Q5 = + *rates_Q5.offset((ind_tmp + NLSF_QUANT_MAX_AMPLITUDE) as isize) as i32; + rate1_Q5 = 280; + } else { + rate0_Q5 = 280 - 43 * 4 + 43 * ind_tmp as i16 as i32; + rate1_Q5 = rate0_Q5 + 43; + } + } else if ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE { + if ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE { + rate0_Q5 = 280; + rate1_Q5 = + *rates_Q5.offset((ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE) as isize) as i32; + } else { + rate0_Q5 = 280 - 43 * 4 + -(43) as i16 as i32 * ind_tmp as i16 as i32; + rate1_Q5 = rate0_Q5 - 43; + } + } else { + rate0_Q5 = *rates_Q5.offset((ind_tmp + NLSF_QUANT_MAX_AMPLITUDE) as isize) as i32; + rate1_Q5 = + *rates_Q5.offset((ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE) as isize) as i32; + } + RD_tmp_Q25 = RD_Q25[j as usize]; + diff_Q10 = in_Q10 - out0_Q10 as i32; + RD_Q25[j as usize] = RD_tmp_Q25 + + diff_Q10 as i16 as i32 * diff_Q10 as i16 as i32 * *w_Q5.offset(i as isize) as i32 + + mu_Q20 as i16 as i32 * rate0_Q5 as i16 as i32; + diff_Q10 = in_Q10 - out1_Q10 as i32; + RD_Q25[(j + nStates) as usize] = RD_tmp_Q25 + + diff_Q10 as i16 as i32 * diff_Q10 as i16 as i32 * *w_Q5.offset(i as isize) as i32 + + mu_Q20 as i16 as i32 * rate1_Q5 as i16 as i32; + j += 1; + } + if nStates <= NLSF_QUANT_DEL_DEC_STATES / 2 { + j = 0; + while j < nStates { + ind[(j + nStates) as usize][i as usize] = + (ind[j as usize][i as usize] as i32 + 1) as i8; + j += 1; + } + nStates = ((nStates as u32) << 1) as i32; + j = nStates; + while j < NLSF_QUANT_DEL_DEC_STATES { + ind[j as usize][i as usize] = ind[(j - nStates) as usize][i as usize]; + j += 1; + } + } else { + j = 0; + while j < NLSF_QUANT_DEL_DEC_STATES { + if RD_Q25[j as usize] > RD_Q25[(j + NLSF_QUANT_DEL_DEC_STATES) as usize] { + RD_max_Q25[j as usize] = RD_Q25[j as usize]; + RD_min_Q25[j as usize] = RD_Q25[(j + NLSF_QUANT_DEL_DEC_STATES) as usize]; + RD_Q25[j as usize] = RD_min_Q25[j as usize]; + RD_Q25[(j + NLSF_QUANT_DEL_DEC_STATES) as usize] = RD_max_Q25[j as usize]; + out0_Q10 = prev_out_Q10[j as usize]; + prev_out_Q10[j as usize] = + prev_out_Q10[(j + NLSF_QUANT_DEL_DEC_STATES) as usize]; + prev_out_Q10[(j + NLSF_QUANT_DEL_DEC_STATES) as usize] = out0_Q10; + ind_sort[j as usize] = j + NLSF_QUANT_DEL_DEC_STATES; + } else { + RD_min_Q25[j as usize] = RD_Q25[j as usize]; + RD_max_Q25[j as usize] = RD_Q25[(j + NLSF_QUANT_DEL_DEC_STATES) as usize]; + ind_sort[j as usize] = j; + } + j += 1; + } + loop { + min_max_Q25 = silk_int32_MAX; + max_min_Q25 = 0; + ind_min_max = 0; + ind_max_min = 0; + j = 0; + while j < NLSF_QUANT_DEL_DEC_STATES { + if min_max_Q25 > RD_max_Q25[j as usize] { + min_max_Q25 = RD_max_Q25[j as usize]; + ind_min_max = j; + } + if max_min_Q25 < RD_min_Q25[j as usize] { + max_min_Q25 = RD_min_Q25[j as usize]; + ind_max_min = j; + } + j += 1; + } + if min_max_Q25 >= max_min_Q25 { + break; + } + ind_sort[ind_max_min as usize] = + ind_sort[ind_min_max as usize] ^ NLSF_QUANT_DEL_DEC_STATES; + RD_Q25[ind_max_min as usize] = + RD_Q25[(ind_min_max + NLSF_QUANT_DEL_DEC_STATES) as usize]; + prev_out_Q10[ind_max_min as usize] = + prev_out_Q10[(ind_min_max + NLSF_QUANT_DEL_DEC_STATES) as usize]; + RD_min_Q25[ind_max_min as usize] = 0; + RD_max_Q25[ind_min_max as usize] = silk_int32_MAX; + memcpy( + (ind[ind_max_min as usize]).as_mut_ptr() as *mut core::ffi::c_void, + (ind[ind_min_max as usize]).as_mut_ptr() as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } + j = 0; + while j < NLSF_QUANT_DEL_DEC_STATES { + ind[j as usize][i as usize] = + (ind[j as usize][i as usize] as i32 + (ind_sort[j as usize] >> 2)) as i8; + j += 1; + } + } + i -= 1; + } + ind_tmp = 0; + min_Q25 = silk_int32_MAX; + j = 0; + while j < 2 * NLSF_QUANT_DEL_DEC_STATES { + if min_Q25 > RD_Q25[j as usize] { + min_Q25 = RD_Q25[j as usize]; + ind_tmp = j; + } + j += 1; + } + j = 0; + while j < order as i32 { + *indices.offset(j as isize) = + ind[(ind_tmp & NLSF_QUANT_DEL_DEC_STATES - 1) as usize][j as usize]; + j += 1; + } + let ref mut fresh0 = *indices.offset(0 as isize); + *fresh0 = (*fresh0 as i32 + (ind_tmp >> 2)) as i8; + return min_Q25; +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_encode.rs b/vendor/unsafe-libopus/src/silk/NLSF_encode.rs new file mode 100644 index 00000000..2c45a7a9 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_encode.rs @@ -0,0 +1,124 @@ +use crate::externs::memcpy; +use crate::silk::define::MAX_LPC_ORDER; +use crate::silk::lin2log::silk_lin2log; +use crate::silk::sort::silk_insertion_sort_increasing; +use crate::silk::structs::silk_NLSF_CB_struct; +use crate::silk::Inlines::silk_DIV32_varQ; +use crate::silk::NLSF_decode::silk_NLSF_decode; +use crate::silk::NLSF_del_dec_quant::silk_NLSF_del_dec_quant; +use crate::silk::NLSF_stabilize::silk_NLSF_stabilize; +use crate::silk::NLSF_unpack::silk_NLSF_unpack; +use crate::silk::NLSF_VQ::silk_NLSF_VQ; + +pub unsafe fn silk_NLSF_encode( + NLSFIndices: *mut i8, + pNLSF_Q15: *mut i16, + psNLSF_CB: &silk_NLSF_CB_struct, + pW_Q2: *const i16, + NLSF_mu_Q20: i32, + nSurvivors: i32, + signalType: i32, +) -> i32 { + let mut i: i32 = 0; + let mut s: i32 = 0; + let mut ind1: i32 = 0; + let mut bestIndex: i32 = 0; + let mut prob_Q8: i32 = 0; + let mut bits_q7: i32 = 0; + let mut W_tmp_Q9: i32 = 0; + let mut ret: i32 = 0; + let mut res_Q10: [i16; 16] = [0; 16]; + let mut NLSF_tmp_Q15: [i16; 16] = [0; 16]; + let mut W_adj_Q5: [i16; 16] = [0; 16]; + let mut pred_Q8: [u8; 16] = [0; 16]; + let mut ec_ix: [i16; 16] = [0; 16]; + assert!((0..=2).contains(&signalType)); + silk_NLSF_stabilize( + std::slice::from_raw_parts_mut(pNLSF_Q15, psNLSF_CB.order as usize), + psNLSF_CB.deltaMin_Q15, + ); + let vla = psNLSF_CB.nVectors as usize; + let mut err_Q24: Vec = ::std::vec::from_elem(0, vla); + silk_NLSF_VQ( + &mut err_Q24, + std::slice::from_raw_parts(pNLSF_Q15, psNLSF_CB.order as usize), + psNLSF_CB.CB1_NLSF_Q8, + psNLSF_CB.CB1_Wght_Q9, + psNLSF_CB.nVectors as usize, + psNLSF_CB.order as usize, + ); + let vla_0 = nSurvivors as usize; + let mut tempIndices1: Vec = ::std::vec::from_elem(0, vla_0); + silk_insertion_sort_increasing( + err_Q24.as_mut_ptr(), + tempIndices1.as_mut_ptr(), + psNLSF_CB.nVectors as i32, + nSurvivors, + ); + let vla_1 = nSurvivors as usize; + let mut RD_Q25: Vec = ::std::vec::from_elem(0, vla_1); + let vla_2 = (nSurvivors * 16) as usize; + let mut tempIndices2: Vec = ::std::vec::from_elem(0, vla_2); + s = 0; + while s < nSurvivors { + ind1 = *tempIndices1.as_mut_ptr().offset(s as isize); + let pCB_element = &psNLSF_CB.CB1_NLSF_Q8[(ind1 * psNLSF_CB.order as i32) as usize..]; + let pCB_Wght_Q9 = &psNLSF_CB.CB1_Wght_Q9[(ind1 * psNLSF_CB.order as i32) as usize..]; + i = 0; + while i < psNLSF_CB.order as i32 { + NLSF_tmp_Q15[i as usize] = ((pCB_element[i as usize] as i16 as u16 as i32) << 7) as i16; + W_tmp_Q9 = pCB_Wght_Q9[i as usize] as i32; + res_Q10[i as usize] = ((*pNLSF_Q15.offset(i as isize) as i32 + - NLSF_tmp_Q15[i as usize] as i32) as i16 as i32 + * W_tmp_Q9 as i16 as i32 + >> 14) as i16; + W_adj_Q5[i as usize] = silk_DIV32_varQ( + *pW_Q2.offset(i as isize) as i32, + W_tmp_Q9 as i16 as i32 * W_tmp_Q9 as i16 as i32, + 21, + ) as i16; + i += 1; + } + silk_NLSF_unpack(&mut ec_ix, &mut pred_Q8, psNLSF_CB, ind1); + *RD_Q25.as_mut_ptr().offset(s as isize) = silk_NLSF_del_dec_quant( + &mut *tempIndices2 + .as_mut_ptr() + .offset((s * MAX_LPC_ORDER) as isize), + res_Q10.as_mut_ptr() as *const i16, + W_adj_Q5.as_mut_ptr() as *const i16, + pred_Q8.as_mut_ptr() as *const u8, + ec_ix.as_mut_ptr() as *const i16, + psNLSF_CB.ec_Rates_Q5, + psNLSF_CB.quantStepSize_Q16 as i32, + psNLSF_CB.invQuantStepSize_Q6, + NLSF_mu_Q20, + psNLSF_CB.order, + ); + let iCDF_ptr = + &(psNLSF_CB.CB1_iCDF)[((signalType >> 1) * psNLSF_CB.nVectors as i32) as usize..]; + if ind1 == 0 { + prob_Q8 = 256 - iCDF_ptr[ind1 as usize] as i32; + } else { + prob_Q8 = iCDF_ptr[(ind1 - 1) as usize] as i32 - iCDF_ptr[ind1 as usize] as i32; + } + bits_q7 = ((8) << 7) - silk_lin2log(prob_Q8); + *RD_Q25.as_mut_ptr().offset(s as isize) = *RD_Q25.as_mut_ptr().offset(s as isize) + + bits_q7 as i16 as i32 * (NLSF_mu_Q20 >> 2) as i16 as i32; + s += 1; + } + silk_insertion_sort_increasing(RD_Q25.as_mut_ptr(), &mut bestIndex, nSurvivors, 1); + *NLSFIndices.offset(0 as isize) = *tempIndices1.as_mut_ptr().offset(bestIndex as isize) as i8; + memcpy( + &mut *NLSFIndices.offset(1 as isize) as *mut i8 as *mut core::ffi::c_void, + &mut *tempIndices2.as_mut_ptr().offset((bestIndex * 16) as isize) as *mut i8 + as *const core::ffi::c_void, + (psNLSF_CB.order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + silk_NLSF_decode( + std::slice::from_raw_parts_mut(pNLSF_Q15, psNLSF_CB.order as usize), + std::slice::from_raw_parts(NLSFIndices, psNLSF_CB.order as usize + 1), + psNLSF_CB, + ); + ret = *RD_Q25.as_mut_ptr().offset(0 as isize); + return ret; +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_stabilize.rs b/vendor/unsafe-libopus/src/silk/NLSF_stabilize.rs new file mode 100644 index 00000000..f38510e7 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_stabilize.rs @@ -0,0 +1,188 @@ +//! NLSF stabilizer: +//! +//! - Moves NLSFs further apart if they are too close +//! - Moves NLSFs away from borders if they are too close +//! - High effort to achieve a modification with minimum +//! Euclidean distance to input vector +//! - Output are sorted NLSF coefficients +//! + +use crate::silk::sort::silk_insertion_sort_increasing_all_values_int16; +use crate::silk::SigProc_FIX::{silk_max_int, silk_min_int}; + +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +pub const MAX_LOOPS: i32 = 20; + +/// NLSF stabilizer, for a single input data vector +pub fn silk_NLSF_stabilize(NLSF_Q15: &mut [i16], NDeltaMin_Q15: &[i16]) { + let mut i: usize = 0; + let mut I: usize = 0; + let mut k: usize = 0; + let mut loops: i32 = 0; + let mut center_freq_Q15: i16 = 0; + let mut diff_Q15: i32 = 0; + let mut min_diff_Q15: i32 = 0; + let mut min_center_Q15: i32 = 0; + let mut max_center_Q15: i32 = 0; + + let L = NLSF_Q15.len(); + + /* This is necessary to ensure an output within range of a opus_int16 */ + assert!(NDeltaMin_Q15[L] >= 1); + + loops = 0; + while loops < MAX_LOOPS { + /**************************/ + /* Find smallest distance */ + /**************************/ + /* First element */ + min_diff_Q15 = NLSF_Q15[0] as i32 - NDeltaMin_Q15[0] as i32; + I = 0; + /* Middle elements */ + i = 1; + while i < L { + diff_Q15 = NLSF_Q15[i] as i32 - (NLSF_Q15[i - 1] as i32 + NDeltaMin_Q15[i] as i32); + if diff_Q15 < min_diff_Q15 { + min_diff_Q15 = diff_Q15; + I = i; + } + i += 1; + } + /* Last element */ + diff_Q15 = ((1) << 15) - (NLSF_Q15[L - 1] as i32 + NDeltaMin_Q15[L] as i32); + if diff_Q15 < min_diff_Q15 { + min_diff_Q15 = diff_Q15; + I = L; + } + + /***************************************************/ + /* Now check if the smallest distance non-negative */ + /***************************************************/ + if min_diff_Q15 >= 0 { + return; + } + if I == 0 { + /* Move away from lower limit */ + NLSF_Q15[0] = NDeltaMin_Q15[0]; + } else if I == L { + /* Move away from higher limit */ + NLSF_Q15[L - 1] = (((1) << 15) - NDeltaMin_Q15[L] as i32) as i16; + } else { + /* Find the lower extreme for the location of the current center frequency */ + min_center_Q15 = 0; + k = 0; + while k < I { + min_center_Q15 += NDeltaMin_Q15[k] as i32; + k += 1; + } + min_center_Q15 += NDeltaMin_Q15[I] as i32 >> 1; + + /* Find the upper extreme for the location of the current center frequency */ + max_center_Q15 = (1) << 15; + k = L; + while k > I { + max_center_Q15 -= NDeltaMin_Q15[k] as i32; + k -= 1; + } + max_center_Q15 -= NDeltaMin_Q15[I] as i32 >> 1; + + /* Move apart, sorted by value, keeping the same center frequency */ + center_freq_Q15 = (if min_center_Q15 > max_center_Q15 { + if (if 1 == 1 { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1) + + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 & 1) + } else { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1 - 1) + 1 >> 1 + }) > min_center_Q15 + { + min_center_Q15 + } else if (if 1 == 1 { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1) + + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 & 1) + } else { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1 - 1) + 1 >> 1 + }) < max_center_Q15 + { + max_center_Q15 + } else if 1 == 1 { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1) + + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 & 1) + } else { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1 - 1) + 1 >> 1 + } + } else if (if 1 == 1 { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1) + + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 & 1) + } else { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1 - 1) + 1 >> 1 + }) > max_center_Q15 + { + max_center_Q15 + } else if (if 1 == 1 { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1) + + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 & 1) + } else { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1 - 1) + 1 >> 1 + }) < min_center_Q15 + { + min_center_Q15 + } else if 1 == 1 { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1) + + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 & 1) + } else { + (NLSF_Q15[I - 1] as i32 + NLSF_Q15[I] as i32 >> 1 - 1) + 1 >> 1 + }) as i16; + NLSF_Q15[I - 1] = (center_freq_Q15 as i32 - (NDeltaMin_Q15[I] as i32 >> 1)) as i16; + NLSF_Q15[I] = (NLSF_Q15[I - 1] as i32 + NDeltaMin_Q15[I] as i32) as i16; + } + loops += 1; + } + + /* Safe and simple fall back method, which is less ideal than the above */ + if loops == MAX_LOOPS { + /* Insertion sort (fast for already almost sorted arrays): */ + /* Best case: O(n) for an already sorted array */ + /* Worst case: O(n^2) for an inversely sorted array */ + silk_insertion_sort_increasing_all_values_int16(NLSF_Q15); + + /* First NLSF should be no less than NDeltaMin[0] */ + NLSF_Q15[0] = silk_max_int(NLSF_Q15[0] as i32, NDeltaMin_Q15[0 as usize] as i32) as i16; + + /* Keep delta_min distance between the NLSFs */ + i = 1; + while i < L { + NLSF_Q15[i] = silk_max_int( + NLSF_Q15[i] as i32, + (if NLSF_Q15[i - 1] as i32 + NDeltaMin_Q15[i] as i32 > silk_int16_MAX { + silk_int16_MAX + } else if (NLSF_Q15[i - 1] as i32 + NDeltaMin_Q15[i] as i32) < silk_int16_MIN { + silk_int16_MIN + } else { + NLSF_Q15[i - 1] as i32 + NDeltaMin_Q15[i] as i32 + }) as i16 as i32, + ) as i16; + i += 1; + } + + /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ + NLSF_Q15[L - 1] = silk_min_int( + NLSF_Q15[L - 1] as i32, + ((1) << 15) - NDeltaMin_Q15[L] as i32, + ) as i16; + + /* Keep NDeltaMin distance between the NLSFs */ + + for i in (0..=L - 2).rev() { + NLSF_Q15[i] = silk_min_int( + NLSF_Q15[i] as i32, + NLSF_Q15[i + 1] as i32 - NDeltaMin_Q15[i + 1] as i32, + ) as i16; + } + } +} diff --git a/vendor/unsafe-libopus/src/silk/NLSF_unpack.rs b/vendor/unsafe-libopus/src/silk/NLSF_unpack.rs new file mode 100644 index 00000000..68274628 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NLSF_unpack.rs @@ -0,0 +1,22 @@ +use crate::silk::structs::silk_NLSF_CB_struct; + +pub fn silk_NLSF_unpack( + ec_ix: &mut [i16], + pred_Q8: &mut [u8], + psNLSF_CB: &silk_NLSF_CB_struct, + CB1_index: i32, +) { + let mut entry: u8 = 0; + let mut ec_sel_ptr = &psNLSF_CB.ec_sel[(CB1_index * psNLSF_CB.order as i32 / 2) as usize..]; + let mut i = 0usize; + while i < psNLSF_CB.order as usize { + entry = ec_sel_ptr[0]; + ec_sel_ptr = &ec_sel_ptr[1..]; + ec_ix[i] = ((entry as i32 >> 1 & 7) as i16 as i32 * (2 * 4 + 1) as i16 as i32) as i16; + pred_Q8[i] = psNLSF_CB.pred_Q8[i + (entry as usize & 1) * (psNLSF_CB.order as usize - 1)]; + ec_ix[i + 1] = ((entry as i32 >> 5 & 7) as i16 as i32 * (2 * 4 + 1) as i16 as i32) as i16; + pred_Q8[i + 1] = + psNLSF_CB.pred_Q8[i + (entry as usize >> 4 & 1) * (psNLSF_CB.order as usize - 1) + 1]; + i += 2; + } +} diff --git a/vendor/unsafe-libopus/src/silk/NSQ.rs b/vendor/unsafe-libopus/src/silk/NSQ.rs new file mode 100644 index 00000000..5dbff663 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NSQ.rs @@ -0,0 +1,575 @@ +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int16_MIN: i32 = i16::MIN as i32; +} +pub mod NSQ_h { + #[inline] + pub unsafe fn silk_noise_shape_quantizer_short_prediction_c( + buf32: *const i32, + coef16: *const i16, + order: i32, + ) -> i32 { + let mut out: i32 = 0; + out = order >> 1; + out = (out as i64 + + (*buf32.offset(0 as isize) as i64 * *coef16.offset(0 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-1 as isize) as i64 * *coef16.offset(1 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(2) as isize) as i64 * *coef16.offset(2 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(3) as isize) as i64 * *coef16.offset(3 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(4) as isize) as i64 * *coef16.offset(4 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(5) as isize) as i64 * *coef16.offset(5 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(6) as isize) as i64 * *coef16.offset(6 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(7) as isize) as i64 * *coef16.offset(7 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(8) as isize) as i64 * *coef16.offset(8 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(9) as isize) as i64 * *coef16.offset(9 as isize) as i64 >> 16)) + as i32; + if order == 16 { + out = (out as i64 + + (*buf32.offset(-(10) as isize) as i64 * *coef16.offset(10 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(11) as isize) as i64 * *coef16.offset(11 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(12) as isize) as i64 * *coef16.offset(12 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(13) as isize) as i64 * *coef16.offset(13 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(14) as isize) as i64 * *coef16.offset(14 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(15) as isize) as i64 * *coef16.offset(15 as isize) as i64 >> 16)) + as i32; + } + return out; + } + #[inline] + pub unsafe fn silk_NSQ_noise_shape_feedback_loop_c( + data0: *const i32, + data1: *mut i32, + coef: *const i16, + order: i32, + ) -> i32 { + let mut out: i32 = 0; + let mut tmp1: i32 = 0; + let mut tmp2: i32 = 0; + let mut j: i32 = 0; + tmp2 = *data0.offset(0 as isize); + tmp1 = *data1.offset(0 as isize); + *data1.offset(0 as isize) = tmp2; + out = order >> 1; + out = (out as i64 + (tmp2 as i64 * *coef.offset(0 as isize) as i64 >> 16)) as i32; + j = 2; + while j < order { + tmp2 = *data1.offset((j - 1) as isize); + *data1.offset((j - 1) as isize) = tmp1; + out = (out as i64 + (tmp1 as i64 * *coef.offset((j - 1) as isize) as i64 >> 16)) as i32; + tmp1 = *data1.offset((j + 0) as isize); + *data1.offset((j + 0) as isize) = tmp2; + out = (out as i64 + (tmp2 as i64 * *coef.offset(j as isize) as i64 >> 16)) as i32; + j += 2; + } + *data1.offset((order - 1) as isize) = tmp1; + out = (out as i64 + (tmp1 as i64 * *coef.offset((order - 1) as isize) as i64 >> 16)) as i32; + out = ((out as u32) << 1) as i32; + return out; + } +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +pub use self::NSQ_h::{ + silk_NSQ_noise_shape_feedback_loop_c, silk_noise_shape_quantizer_short_prediction_c, +}; +use crate::externs::{memcpy, memmove}; +use crate::silk::define::{ + HARM_SHAPE_FIR_TAPS, LTP_ORDER, MAX_LPC_ORDER, MAX_SHAPE_LPC_ORDER, NSQ_LPC_BUF_LENGTH, + TYPE_VOICED, +}; +use crate::silk::structs::{silk_encoder_state, silk_nsq_state, SideInfoIndices}; +use crate::silk::tables_other::silk_Quantization_Offsets_Q10; +use crate::silk::Inlines::{silk_DIV32_varQ, silk_INVERSE32_varQ}; +use crate::silk::LPC_analysis_filter::silk_LPC_analysis_filter; + +pub unsafe fn silk_NSQ_c( + psEncC: *const silk_encoder_state, + NSQ: *mut silk_nsq_state, + psIndices: *mut SideInfoIndices, + mut x16: *const i16, + mut pulses: *mut i8, + PredCoef_Q12: *const i16, + LTPCoef_Q14: *const i16, + AR_Q13: *const i16, + HarmShapeGain_Q14: *const i32, + Tilt_Q14: *const i32, + LF_shp_Q14: *const i32, + Gains_Q16: *const i32, + pitchL: *const i32, + Lambda_Q10: i32, + LTP_scale_Q14: i32, +) { + let mut k: i32 = 0; + let mut lag: i32 = 0; + let mut start_idx: i32 = 0; + let mut LSF_interpolation_flag: i32 = 0; + let mut A_Q12: *const i16 = 0 as *const i16; + let mut B_Q14: *const i16 = 0 as *const i16; + let mut AR_shp_Q13: *const i16 = 0 as *const i16; + let mut pxq: *mut i16 = 0 as *mut i16; + let mut HarmShapeFIRPacked_Q14: i32 = 0; + let mut offset_Q10: i32 = 0; + (*NSQ).rand_seed = (*psIndices).Seed as i32; + lag = (*NSQ).lagPrev; + offset_Q10 = silk_Quantization_Offsets_Q10[((*psIndices).signalType as i32 >> 1) as usize] + [(*psIndices).quantOffsetType as usize] as i32; + if (*psIndices).NLSFInterpCoef_Q2 as i32 == 4 { + LSF_interpolation_flag = 0; + } else { + LSF_interpolation_flag = 1; + } + let vla = ((*psEncC).ltp_mem_length + (*psEncC).frame_length) as usize; + let mut sLTP_Q15: Vec = ::std::vec::from_elem(0, vla); + let vla_0 = ((*psEncC).ltp_mem_length + (*psEncC).frame_length) as usize; + let mut sLTP: Vec = ::std::vec::from_elem(0, vla_0); + let vla_1 = (*psEncC).subfr_length as usize; + let mut x_sc_Q10: Vec = ::std::vec::from_elem(0, vla_1); + (*NSQ).sLTP_shp_buf_idx = (*psEncC).ltp_mem_length; + (*NSQ).sLTP_buf_idx = (*psEncC).ltp_mem_length; + pxq = &mut *((*NSQ).xq) + .as_mut_ptr() + .offset((*psEncC).ltp_mem_length as isize) as *mut i16; + k = 0; + while k < (*psEncC).nb_subfr { + A_Q12 = &*PredCoef_Q12 + .offset(((k >> 1 | 1 - LSF_interpolation_flag) * MAX_LPC_ORDER) as isize) + as *const i16; + B_Q14 = &*LTPCoef_Q14.offset((k * LTP_ORDER) as isize) as *const i16; + AR_shp_Q13 = &*AR_Q13.offset((k * MAX_SHAPE_LPC_ORDER) as isize) as *const i16; + HarmShapeFIRPacked_Q14 = *HarmShapeGain_Q14.offset(k as isize) >> 2; + HarmShapeFIRPacked_Q14 |= + (((*HarmShapeGain_Q14.offset(k as isize) >> 1) as u32) << 16) as i32; + (*NSQ).rewhite_flag = 0; + if (*psIndices).signalType as i32 == TYPE_VOICED { + lag = *pitchL.offset(k as isize); + if k & 3 - ((LSF_interpolation_flag as u32) << 1) as i32 == 0 { + start_idx = + (*psEncC).ltp_mem_length - lag - (*psEncC).predictLPCOrder - LTP_ORDER / 2; + assert!(start_idx > 0); + silk_LPC_analysis_filter( + &mut *sLTP.as_mut_ptr().offset(start_idx as isize), + &mut *((*NSQ).xq) + .as_mut_ptr() + .offset((start_idx + k * (*psEncC).subfr_length) as isize), + A_Q12, + (*psEncC).ltp_mem_length - start_idx, + (*psEncC).predictLPCOrder, + (*psEncC).arch, + ); + (*NSQ).rewhite_flag = 1; + (*NSQ).sLTP_buf_idx = (*psEncC).ltp_mem_length; + } + } + silk_nsq_scale_states( + psEncC, + NSQ, + x16, + x_sc_Q10.as_mut_ptr(), + sLTP.as_mut_ptr() as *const i16, + sLTP_Q15.as_mut_ptr(), + k, + LTP_scale_Q14, + Gains_Q16, + pitchL, + (*psIndices).signalType as i32, + ); + silk_noise_shape_quantizer( + NSQ, + (*psIndices).signalType as i32, + x_sc_Q10.as_mut_ptr() as *const i32, + pulses, + pxq, + sLTP_Q15.as_mut_ptr(), + A_Q12, + B_Q14, + AR_shp_Q13, + lag, + HarmShapeFIRPacked_Q14, + *Tilt_Q14.offset(k as isize), + *LF_shp_Q14.offset(k as isize), + *Gains_Q16.offset(k as isize), + Lambda_Q10, + offset_Q10, + (*psEncC).subfr_length, + (*psEncC).shapingLPCOrder, + (*psEncC).predictLPCOrder, + (*psEncC).arch, + ); + x16 = x16.offset((*psEncC).subfr_length as isize); + pulses = pulses.offset((*psEncC).subfr_length as isize); + pxq = pxq.offset((*psEncC).subfr_length as isize); + k += 1; + } + (*NSQ).lagPrev = *pitchL.offset(((*psEncC).nb_subfr - 1) as isize); + memmove( + ((*NSQ).xq).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*NSQ).xq) + .as_mut_ptr() + .offset((*psEncC).frame_length as isize) as *mut i16 + as *const core::ffi::c_void, + ((*psEncC).ltp_mem_length as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + memmove( + ((*NSQ).sLTP_shp_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*NSQ).sLTP_shp_Q14) + .as_mut_ptr() + .offset((*psEncC).frame_length as isize) as *mut i32 + as *const core::ffi::c_void, + ((*psEncC).ltp_mem_length as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); +} +#[inline] +unsafe fn silk_noise_shape_quantizer( + NSQ: *mut silk_nsq_state, + signalType: i32, + x_sc_Q10: *const i32, + pulses: *mut i8, + xq: *mut i16, + sLTP_Q15: *mut i32, + a_Q12: *const i16, + b_Q14: *const i16, + AR_shp_Q13: *const i16, + lag: i32, + HarmShapeFIRPacked_Q14: i32, + Tilt_Q14: i32, + LF_shp_Q14: i32, + Gain_Q16: i32, + Lambda_Q10: i32, + offset_Q10: i32, + length: i32, + shapingLPCOrder: i32, + predictLPCOrder: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut LTP_pred_Q13: i32 = 0; + let mut LPC_pred_Q10: i32 = 0; + let mut n_AR_Q12: i32 = 0; + let mut n_LTP_Q13: i32 = 0; + let mut n_LF_Q12: i32 = 0; + let mut r_Q10: i32 = 0; + let mut rr_Q10: i32 = 0; + let mut q1_Q0: i32 = 0; + let mut q1_Q10: i32 = 0; + let mut q2_Q10: i32 = 0; + let mut rd1_Q20: i32 = 0; + let mut rd2_Q20: i32 = 0; + let mut exc_Q14: i32 = 0; + let mut LPC_exc_Q14: i32 = 0; + let mut xq_Q14: i32 = 0; + let mut Gain_Q10: i32 = 0; + let mut tmp1: i32 = 0; + let mut tmp2: i32 = 0; + let mut sLF_AR_shp_Q14: i32 = 0; + let mut psLPC_Q14: *mut i32 = 0 as *mut i32; + let mut shp_lag_ptr: *mut i32 = 0 as *mut i32; + let mut pred_lag_ptr: *mut i32 = 0 as *mut i32; + shp_lag_ptr = &mut *((*NSQ).sLTP_shp_Q14) + .as_mut_ptr() + .offset(((*NSQ).sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2) as isize) + as *mut i32; + pred_lag_ptr = + &mut *sLTP_Q15.offset(((*NSQ).sLTP_buf_idx - lag + LTP_ORDER / 2) as isize) as *mut i32; + Gain_Q10 = Gain_Q16 >> 6; + psLPC_Q14 = &mut *((*NSQ).sLPC_Q14) + .as_mut_ptr() + .offset((NSQ_LPC_BUF_LENGTH - 1) as isize) as *mut i32; + i = 0; + while i < length { + (*NSQ).rand_seed = + 907633515_u32.wrapping_add(((*NSQ).rand_seed as u32).wrapping_mul(196314165)) as i32; + LPC_pred_Q10 = + silk_noise_shape_quantizer_short_prediction_c(psLPC_Q14, a_Q12, predictLPCOrder); + if signalType == TYPE_VOICED { + LTP_pred_Q13 = 2; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(0 as isize) as i64 * *b_Q14.offset(0 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-1 as isize) as i64 * *b_Q14.offset(1 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-(2) as isize) as i64 * *b_Q14.offset(2 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-(3) as isize) as i64 * *b_Q14.offset(3 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-(4) as isize) as i64 * *b_Q14.offset(4 as isize) as i64 + >> 16)) as i32; + pred_lag_ptr = pred_lag_ptr.offset(1); + } else { + LTP_pred_Q13 = 0; + } + assert!(shapingLPCOrder & 1 == 0); + n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop_c( + &mut (*NSQ).sDiff_shp_Q14, + ((*NSQ).sAR2_Q14).as_mut_ptr(), + AR_shp_Q13, + shapingLPCOrder, + ); + n_AR_Q12 = (n_AR_Q12 as i64 + ((*NSQ).sLF_AR_shp_Q14 as i64 * Tilt_Q14 as i16 as i64 >> 16)) + as i32; + n_LF_Q12 = ((*NSQ).sLTP_shp_Q14[((*NSQ).sLTP_shp_buf_idx - 1) as usize] as i64 + * LF_shp_Q14 as i16 as i64 + >> 16) as i32; + n_LF_Q12 = (n_LF_Q12 as i64 + + ((*NSQ).sLF_AR_shp_Q14 as i64 * (LF_shp_Q14 as i64 >> 16) >> 16)) + as i32; + assert!(lag > 0 || signalType != 2); + tmp1 = ((LPC_pred_Q10 as u32) << 2) as i32 - n_AR_Q12; + tmp1 = tmp1 - n_LF_Q12; + if lag > 0 { + n_LTP_Q13 = ((*shp_lag_ptr.offset(0 as isize) + *shp_lag_ptr.offset(-(2) as isize)) + as i64 + * HarmShapeFIRPacked_Q14 as i16 as i64 + >> 16) as i32; + n_LTP_Q13 = (n_LTP_Q13 as i64 + + (*shp_lag_ptr.offset(-1 as isize) as i64 * (HarmShapeFIRPacked_Q14 as i64 >> 16) + >> 16)) as i32; + n_LTP_Q13 = ((n_LTP_Q13 as u32) << 1) as i32; + shp_lag_ptr = shp_lag_ptr.offset(1); + tmp2 = LTP_pred_Q13 - n_LTP_Q13; + tmp1 = tmp2 + ((tmp1 as u32) << 1) as i32; + tmp1 = if 3 == 1 { + (tmp1 >> 1) + (tmp1 & 1) + } else { + (tmp1 >> 3 - 1) + 1 >> 1 + }; + } else { + tmp1 = if 2 == 1 { + (tmp1 >> 1) + (tmp1 & 1) + } else { + (tmp1 >> 2 - 1) + 1 >> 1 + }; + } + r_Q10 = *x_sc_Q10.offset(i as isize) - tmp1; + if (*NSQ).rand_seed < 0 { + r_Q10 = -r_Q10; + } + r_Q10 = if -((31) << 10) > (30) << 10 { + if r_Q10 > -((31) << 10) { + -((31) << 10) + } else if r_Q10 < (30) << 10 { + (30) << 10 + } else { + r_Q10 + } + } else if r_Q10 > (30) << 10 { + (30) << 10 + } else if r_Q10 < -((31) << 10) { + -((31) << 10) + } else { + r_Q10 + }; + q1_Q10 = r_Q10 - offset_Q10; + q1_Q0 = q1_Q10 >> 10; + if Lambda_Q10 > 2048 { + let rdo_offset: i32 = Lambda_Q10 / 2 - 512; + if q1_Q10 > rdo_offset { + q1_Q0 = q1_Q10 - rdo_offset >> 10; + } else if q1_Q10 < -rdo_offset { + q1_Q0 = q1_Q10 + rdo_offset >> 10; + } else if q1_Q10 < 0 { + q1_Q0 = -1; + } else { + q1_Q0 = 0; + } + } + if q1_Q0 > 0 { + q1_Q10 = ((q1_Q0 as u32) << 10) as i32 - 80; + q1_Q10 = q1_Q10 + offset_Q10; + q2_Q10 = q1_Q10 + 1024; + rd1_Q20 = q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q20 = q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } else if q1_Q0 == 0 { + q1_Q10 = offset_Q10; + q2_Q10 = q1_Q10 + (1024 - 80); + rd1_Q20 = q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q20 = q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } else if q1_Q0 == -1 { + q2_Q10 = offset_Q10; + q1_Q10 = q2_Q10 - (1024 - 80); + rd1_Q20 = -q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q20 = q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } else { + q1_Q10 = ((q1_Q0 as u32) << 10) as i32 + 80; + q1_Q10 = q1_Q10 + offset_Q10; + q2_Q10 = q1_Q10 + 1024; + rd1_Q20 = -q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q20 = -q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } + rr_Q10 = r_Q10 - q1_Q10; + rd1_Q20 = rd1_Q20 + rr_Q10 as i16 as i32 * rr_Q10 as i16 as i32; + rr_Q10 = r_Q10 - q2_Q10; + rd2_Q20 = rd2_Q20 + rr_Q10 as i16 as i32 * rr_Q10 as i16 as i32; + if rd2_Q20 < rd1_Q20 { + q1_Q10 = q2_Q10; + } + *pulses.offset(i as isize) = (if 10 == 1 { + (q1_Q10 >> 1) + (q1_Q10 & 1) + } else { + (q1_Q10 >> 10 - 1) + 1 >> 1 + }) as i8; + exc_Q14 = ((q1_Q10 as u32) << 4) as i32; + if (*NSQ).rand_seed < 0 { + exc_Q14 = -exc_Q14; + } + LPC_exc_Q14 = exc_Q14 + ((LTP_pred_Q13 as u32) << 1) as i32; + xq_Q14 = LPC_exc_Q14 + ((LPC_pred_Q10 as u32) << 4) as i32; + *xq.offset(i as isize) = (if (if 8 == 1 { + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 >> 1) + + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 & 1) + } else { + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 >> 8 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 >> 1) + + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 & 1) + } else { + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 >> 8 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 >> 1) + + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 & 1) + } else { + ((xq_Q14 as i64 * Gain_Q10 as i64 >> 16) as i32 >> 8 - 1) + 1 >> 1 + }) as i16; + psLPC_Q14 = psLPC_Q14.offset(1); + *psLPC_Q14 = xq_Q14; + (*NSQ).sDiff_shp_Q14 = xq_Q14 - ((*x_sc_Q10.offset(i as isize) as u32) << 4) as i32; + sLF_AR_shp_Q14 = (*NSQ).sDiff_shp_Q14 - ((n_AR_Q12 as u32) << 2) as i32; + (*NSQ).sLF_AR_shp_Q14 = sLF_AR_shp_Q14; + (*NSQ).sLTP_shp_Q14[(*NSQ).sLTP_shp_buf_idx as usize] = + sLF_AR_shp_Q14 - ((n_LF_Q12 as u32) << 2) as i32; + *sLTP_Q15.offset((*NSQ).sLTP_buf_idx as isize) = ((LPC_exc_Q14 as u32) << 1) as i32; + (*NSQ).sLTP_shp_buf_idx += 1; + (*NSQ).sLTP_buf_idx += 1; + (*NSQ).rand_seed = + ((*NSQ).rand_seed as u32).wrapping_add(*pulses.offset(i as isize) as u32) as i32; + i += 1; + } + memcpy( + ((*NSQ).sLPC_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*NSQ).sLPC_Q14).as_mut_ptr().offset(length as isize) as *mut i32 + as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); +} +#[inline] +unsafe fn silk_nsq_scale_states( + psEncC: *const silk_encoder_state, + NSQ: *mut silk_nsq_state, + x16: *const i16, + x_sc_Q10: *mut i32, + sLTP: *const i16, + sLTP_Q15: *mut i32, + subfr: i32, + LTP_scale_Q14: i32, + Gains_Q16: *const i32, + pitchL: *const i32, + signal_type: i32, +) { + let mut i: i32 = 0; + let mut lag: i32 = 0; + let mut gain_adj_Q16: i32 = 0; + let mut inv_gain_Q31: i32 = 0; + let mut inv_gain_Q26: i32 = 0; + lag = *pitchL.offset(subfr as isize); + inv_gain_Q31 = silk_INVERSE32_varQ( + if *Gains_Q16.offset(subfr as isize) > 1 { + *Gains_Q16.offset(subfr as isize) + } else { + 1 + }, + 47, + ); + inv_gain_Q26 = if 5 == 1 { + (inv_gain_Q31 >> 1) + (inv_gain_Q31 & 1) + } else { + (inv_gain_Q31 >> 5 - 1) + 1 >> 1 + }; + i = 0; + while i < (*psEncC).subfr_length { + *x_sc_Q10.offset(i as isize) = + (*x16.offset(i as isize) as i64 * inv_gain_Q26 as i64 >> 16) as i32; + i += 1; + } + if (*NSQ).rewhite_flag != 0 { + if subfr == 0 { + inv_gain_Q31 = (((inv_gain_Q31 as i64 * LTP_scale_Q14 as i16 as i64 >> 16) as i32 + as u32) + << 2) as i32; + } + i = (*NSQ).sLTP_buf_idx - lag - LTP_ORDER / 2; + while i < (*NSQ).sLTP_buf_idx { + *sLTP_Q15.offset(i as isize) = + (inv_gain_Q31 as i64 * *sLTP.offset(i as isize) as i64 >> 16) as i32; + i += 1; + } + } + if *Gains_Q16.offset(subfr as isize) != (*NSQ).prev_gain_Q16 { + gain_adj_Q16 = silk_DIV32_varQ((*NSQ).prev_gain_Q16, *Gains_Q16.offset(subfr as isize), 16); + i = (*NSQ).sLTP_shp_buf_idx - (*psEncC).ltp_mem_length; + while i < (*NSQ).sLTP_shp_buf_idx { + (*NSQ).sLTP_shp_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*NSQ).sLTP_shp_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + if signal_type == TYPE_VOICED && (*NSQ).rewhite_flag == 0 { + i = (*NSQ).sLTP_buf_idx - lag - LTP_ORDER / 2; + while i < (*NSQ).sLTP_buf_idx { + *sLTP_Q15.offset(i as isize) = + (gain_adj_Q16 as i64 * *sLTP_Q15.offset(i as isize) as i64 >> 16) as i32; + i += 1; + } + } + (*NSQ).sLF_AR_shp_Q14 = (gain_adj_Q16 as i64 * (*NSQ).sLF_AR_shp_Q14 as i64 >> 16) as i32; + (*NSQ).sDiff_shp_Q14 = (gain_adj_Q16 as i64 * (*NSQ).sDiff_shp_Q14 as i64 >> 16) as i32; + i = 0; + while i < NSQ_LPC_BUF_LENGTH { + (*NSQ).sLPC_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*NSQ).sLPC_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + i = 0; + while i < MAX_SHAPE_LPC_ORDER { + (*NSQ).sAR2_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*NSQ).sAR2_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + (*NSQ).prev_gain_Q16 = *Gains_Q16.offset(subfr as isize); + } +} diff --git a/vendor/unsafe-libopus/src/silk/NSQ_del_dec.rs b/vendor/unsafe-libopus/src/silk/NSQ_del_dec.rs new file mode 100644 index 00000000..5cbd1197 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/NSQ_del_dec.rs @@ -0,0 +1,1070 @@ +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +pub mod NSQ_h { + #[inline] + pub unsafe fn silk_noise_shape_quantizer_short_prediction_c( + buf32: *const i32, + coef16: *const i16, + order: i32, + ) -> i32 { + let mut out: i32 = 0; + out = order >> 1; + out = (out as i64 + + (*buf32.offset(0 as isize) as i64 * *coef16.offset(0 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-1 as isize) as i64 * *coef16.offset(1 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(2) as isize) as i64 * *coef16.offset(2 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(3) as isize) as i64 * *coef16.offset(3 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(4) as isize) as i64 * *coef16.offset(4 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(5) as isize) as i64 * *coef16.offset(5 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(6) as isize) as i64 * *coef16.offset(6 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(7) as isize) as i64 * *coef16.offset(7 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(8) as isize) as i64 * *coef16.offset(8 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(9) as isize) as i64 * *coef16.offset(9 as isize) as i64 >> 16)) + as i32; + if order == 16 { + out = (out as i64 + + (*buf32.offset(-(10) as isize) as i64 * *coef16.offset(10 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(11) as isize) as i64 * *coef16.offset(11 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(12) as isize) as i64 * *coef16.offset(12 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(13) as isize) as i64 * *coef16.offset(13 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(14) as isize) as i64 * *coef16.offset(14 as isize) as i64 >> 16)) + as i32; + out = (out as i64 + + (*buf32.offset(-(15) as isize) as i64 * *coef16.offset(15 as isize) as i64 >> 16)) + as i32; + } + return out; + } +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN, silk_int32_MAX}; +pub use self::NSQ_h::silk_noise_shape_quantizer_short_prediction_c; +use crate::externs::{memcpy, memmove, memset}; +use crate::silk::define::{ + DECISION_DELAY, HARM_SHAPE_FIR_TAPS, LTP_ORDER, MAX_LPC_ORDER, MAX_SHAPE_LPC_ORDER, + NSQ_LPC_BUF_LENGTH, TYPE_VOICED, +}; +use crate::silk::structs::{silk_encoder_state, silk_nsq_state, SideInfoIndices}; +use crate::silk::tables_other::silk_Quantization_Offsets_Q10; +use crate::silk::Inlines::{silk_DIV32_varQ, silk_INVERSE32_varQ}; +use crate::silk::LPC_analysis_filter::silk_LPC_analysis_filter; +use crate::silk::SigProc_FIX::silk_min_int; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct NSQ_del_dec_struct { + pub sLPC_Q14: [i32; 96], + pub RandState: [i32; 40], + pub Q_Q10: [i32; 40], + pub Xq_Q14: [i32; 40], + pub Pred_Q15: [i32; 40], + pub Shape_Q14: [i32; 40], + pub sAR2_Q14: [i32; 24], + pub LF_AR_Q14: i32, + pub Diff_Q14: i32, + pub Seed: i32, + pub SeedInit: i32, + pub RD_Q10: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct NSQ_sample_struct { + pub Q_Q10: i32, + pub RD_Q10: i32, + pub xq_Q14: i32, + pub LF_AR_Q14: i32, + pub Diff_Q14: i32, + pub sLTP_shp_Q14: i32, + pub LPC_exc_Q14: i32, +} +pub type NSQ_sample_pair = [NSQ_sample_struct; 2]; +pub unsafe fn silk_NSQ_del_dec_c( + psEncC: *const silk_encoder_state, + NSQ: *mut silk_nsq_state, + psIndices: *mut SideInfoIndices, + mut x16: *const i16, + mut pulses: *mut i8, + PredCoef_Q12: *const i16, + LTPCoef_Q14: *const i16, + AR_Q13: *const i16, + HarmShapeGain_Q14: *const i32, + Tilt_Q14: *const i32, + LF_shp_Q14: *const i32, + Gains_Q16: *const i32, + pitchL: *const i32, + Lambda_Q10: i32, + LTP_scale_Q14: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut lag: i32 = 0; + let mut start_idx: i32 = 0; + let mut LSF_interpolation_flag: i32 = 0; + let mut Winner_ind: i32 = 0; + let mut subfr: i32 = 0; + let mut last_smple_idx: i32 = 0; + let mut smpl_buf_idx: i32 = 0; + let mut decisionDelay: i32 = 0; + let mut A_Q12: *const i16 = 0 as *const i16; + let mut B_Q14: *const i16 = 0 as *const i16; + let mut AR_shp_Q13: *const i16 = 0 as *const i16; + let mut pxq: *mut i16 = 0 as *mut i16; + let mut HarmShapeFIRPacked_Q14: i32 = 0; + let mut offset_Q10: i32 = 0; + let mut RDmin_Q10: i32 = 0; + let mut Gain_Q10: i32 = 0; + let mut psDD: *mut NSQ_del_dec_struct = 0 as *mut NSQ_del_dec_struct; + lag = (*NSQ).lagPrev; + let vla = (*psEncC).nStatesDelayedDecision as usize; + let mut psDelDec: Vec = ::std::vec::from_elem( + NSQ_del_dec_struct { + sLPC_Q14: [0; 96], + RandState: [0; 40], + Q_Q10: [0; 40], + Xq_Q14: [0; 40], + Pred_Q15: [0; 40], + Shape_Q14: [0; 40], + sAR2_Q14: [0; 24], + LF_AR_Q14: 0, + Diff_Q14: 0, + Seed: 0, + SeedInit: 0, + RD_Q10: 0, + }, + vla, + ); + memset( + psDelDec.as_mut_ptr() as *mut core::ffi::c_void, + 0, + ((*psEncC).nStatesDelayedDecision as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + k = 0; + while k < (*psEncC).nStatesDelayedDecision { + psDD = &mut *psDelDec.as_mut_ptr().offset(k as isize) as *mut NSQ_del_dec_struct; + (*psDD).Seed = k + (*psIndices).Seed as i32 & 3; + (*psDD).SeedInit = (*psDD).Seed; + (*psDD).RD_Q10 = 0; + (*psDD).LF_AR_Q14 = (*NSQ).sLF_AR_shp_Q14; + (*psDD).Diff_Q14 = (*NSQ).sDiff_shp_Q14; + (*psDD).Shape_Q14[0 as usize] = + (*NSQ).sLTP_shp_Q14[((*psEncC).ltp_mem_length - 1) as usize]; + memcpy( + ((*psDD).sLPC_Q14).as_mut_ptr() as *mut core::ffi::c_void, + ((*NSQ).sLPC_Q14).as_mut_ptr() as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*psDD).sAR2_Q14).as_mut_ptr() as *mut core::ffi::c_void, + ((*NSQ).sAR2_Q14).as_mut_ptr() as *const core::ffi::c_void, + ::core::mem::size_of::<[i32; 24]>() as u64, + ); + k += 1; + } + offset_Q10 = silk_Quantization_Offsets_Q10[((*psIndices).signalType as i32 >> 1) as usize] + [(*psIndices).quantOffsetType as usize] as i32; + smpl_buf_idx = 0; + decisionDelay = silk_min_int(DECISION_DELAY, (*psEncC).subfr_length); + if (*psIndices).signalType as i32 == TYPE_VOICED { + k = 0; + while k < (*psEncC).nb_subfr { + decisionDelay = silk_min_int( + decisionDelay, + *pitchL.offset(k as isize) - LTP_ORDER / 2 - 1, + ); + k += 1; + } + } else if lag > 0 { + decisionDelay = silk_min_int(decisionDelay, lag - LTP_ORDER / 2 - 1); + } + if (*psIndices).NLSFInterpCoef_Q2 as i32 == 4 { + LSF_interpolation_flag = 0; + } else { + LSF_interpolation_flag = 1; + } + let vla_0 = ((*psEncC).ltp_mem_length + (*psEncC).frame_length) as usize; + let mut sLTP_Q15: Vec = ::std::vec::from_elem(0, vla_0); + let vla_1 = ((*psEncC).ltp_mem_length + (*psEncC).frame_length) as usize; + let mut sLTP: Vec = ::std::vec::from_elem(0, vla_1); + let vla_2 = (*psEncC).subfr_length as usize; + let mut x_sc_Q10: Vec = ::std::vec::from_elem(0, vla_2); + let mut delayedGain_Q10: [i32; 40] = [0; 40]; + pxq = &mut *((*NSQ).xq) + .as_mut_ptr() + .offset((*psEncC).ltp_mem_length as isize) as *mut i16; + (*NSQ).sLTP_shp_buf_idx = (*psEncC).ltp_mem_length; + (*NSQ).sLTP_buf_idx = (*psEncC).ltp_mem_length; + subfr = 0; + k = 0; + while k < (*psEncC).nb_subfr { + A_Q12 = &*PredCoef_Q12 + .offset(((k >> 1 | 1 - LSF_interpolation_flag) * MAX_LPC_ORDER) as isize) + as *const i16; + B_Q14 = &*LTPCoef_Q14.offset((k * LTP_ORDER) as isize) as *const i16; + AR_shp_Q13 = &*AR_Q13.offset((k * MAX_SHAPE_LPC_ORDER) as isize) as *const i16; + HarmShapeFIRPacked_Q14 = *HarmShapeGain_Q14.offset(k as isize) >> 2; + HarmShapeFIRPacked_Q14 |= + (((*HarmShapeGain_Q14.offset(k as isize) >> 1) as u32) << 16) as i32; + (*NSQ).rewhite_flag = 0; + if (*psIndices).signalType as i32 == TYPE_VOICED { + lag = *pitchL.offset(k as isize); + if k & 3 - ((LSF_interpolation_flag as u32) << 1) as i32 == 0 { + if k == 2 { + RDmin_Q10 = (*psDelDec.as_mut_ptr().offset(0 as isize)).RD_Q10; + Winner_ind = 0; + i = 1; + while i < (*psEncC).nStatesDelayedDecision { + if (*psDelDec.as_mut_ptr().offset(i as isize)).RD_Q10 < RDmin_Q10 { + RDmin_Q10 = (*psDelDec.as_mut_ptr().offset(i as isize)).RD_Q10; + Winner_ind = i; + } + i += 1; + } + i = 0; + while i < (*psEncC).nStatesDelayedDecision { + if i != Winner_ind { + let ref mut fresh0 = (*psDelDec.as_mut_ptr().offset(i as isize)).RD_Q10; + *fresh0 += silk_int32_MAX >> 4; + } + i += 1; + } + psDD = &mut *psDelDec.as_mut_ptr().offset(Winner_ind as isize) + as *mut NSQ_del_dec_struct; + last_smple_idx = smpl_buf_idx + decisionDelay; + i = 0; + while i < decisionDelay { + last_smple_idx = (last_smple_idx - 1) % DECISION_DELAY; + if last_smple_idx < 0 { + last_smple_idx += DECISION_DELAY; + } + *pulses.offset((i - decisionDelay) as isize) = (if 10 == 1 { + ((*psDD).Q_Q10[last_smple_idx as usize] >> 1) + + ((*psDD).Q_Q10[last_smple_idx as usize] & 1) + } else { + ((*psDD).Q_Q10[last_smple_idx as usize] >> 10 - 1) + 1 >> 1 + }) + as i8; + *pxq.offset((i - decisionDelay) as isize) = (if (if 14 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + >> 14 - 1) + + 1 + >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 14 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + >> 14 - 1) + + 1 + >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 14 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *Gains_Q16.offset(1 as isize) as i64 + >> 16) as i32 + >> 14 - 1) + + 1 + >> 1 + }) + as i16; + (*NSQ).sLTP_shp_Q14 + [((*NSQ).sLTP_shp_buf_idx - decisionDelay + i) as usize] = + (*psDD).Shape_Q14[last_smple_idx as usize]; + i += 1; + } + subfr = 0; + } + start_idx = + (*psEncC).ltp_mem_length - lag - (*psEncC).predictLPCOrder - LTP_ORDER / 2; + assert!(start_idx > 0); + silk_LPC_analysis_filter( + &mut *sLTP.as_mut_ptr().offset(start_idx as isize), + &mut *((*NSQ).xq) + .as_mut_ptr() + .offset((start_idx + k * (*psEncC).subfr_length) as isize), + A_Q12, + (*psEncC).ltp_mem_length - start_idx, + (*psEncC).predictLPCOrder, + (*psEncC).arch, + ); + (*NSQ).sLTP_buf_idx = (*psEncC).ltp_mem_length; + (*NSQ).rewhite_flag = 1; + } + } + silk_nsq_del_dec_scale_states( + psEncC, + NSQ, + psDelDec.as_mut_ptr(), + x16, + x_sc_Q10.as_mut_ptr(), + sLTP.as_mut_ptr() as *const i16, + sLTP_Q15.as_mut_ptr(), + k, + (*psEncC).nStatesDelayedDecision, + LTP_scale_Q14, + Gains_Q16, + pitchL, + (*psIndices).signalType as i32, + decisionDelay, + ); + let fresh1 = subfr; + subfr = subfr + 1; + silk_noise_shape_quantizer_del_dec( + NSQ, + psDelDec.as_mut_ptr(), + (*psIndices).signalType as i32, + x_sc_Q10.as_mut_ptr() as *const i32, + pulses, + pxq, + sLTP_Q15.as_mut_ptr(), + delayedGain_Q10.as_mut_ptr(), + A_Q12, + B_Q14, + AR_shp_Q13, + lag, + HarmShapeFIRPacked_Q14, + *Tilt_Q14.offset(k as isize), + *LF_shp_Q14.offset(k as isize), + *Gains_Q16.offset(k as isize), + Lambda_Q10, + offset_Q10, + (*psEncC).subfr_length, + fresh1, + (*psEncC).shapingLPCOrder, + (*psEncC).predictLPCOrder, + (*psEncC).warping_Q16, + (*psEncC).nStatesDelayedDecision, + &mut smpl_buf_idx, + decisionDelay, + (*psEncC).arch, + ); + x16 = x16.offset((*psEncC).subfr_length as isize); + pulses = pulses.offset((*psEncC).subfr_length as isize); + pxq = pxq.offset((*psEncC).subfr_length as isize); + k += 1; + } + RDmin_Q10 = (*psDelDec.as_mut_ptr().offset(0 as isize)).RD_Q10; + Winner_ind = 0; + k = 1; + while k < (*psEncC).nStatesDelayedDecision { + if (*psDelDec.as_mut_ptr().offset(k as isize)).RD_Q10 < RDmin_Q10 { + RDmin_Q10 = (*psDelDec.as_mut_ptr().offset(k as isize)).RD_Q10; + Winner_ind = k; + } + k += 1; + } + psDD = &mut *psDelDec.as_mut_ptr().offset(Winner_ind as isize) as *mut NSQ_del_dec_struct; + (*psIndices).Seed = (*psDD).SeedInit as i8; + last_smple_idx = smpl_buf_idx + decisionDelay; + Gain_Q10 = *Gains_Q16.offset(((*psEncC).nb_subfr - 1) as isize) >> 6; + i = 0; + while i < decisionDelay { + last_smple_idx = (last_smple_idx - 1) % DECISION_DELAY; + if last_smple_idx < 0 { + last_smple_idx += DECISION_DELAY; + } + *pulses.offset((i - decisionDelay) as isize) = (if 10 == 1 { + ((*psDD).Q_Q10[last_smple_idx as usize] >> 1) + + ((*psDD).Q_Q10[last_smple_idx as usize] & 1) + } else { + ((*psDD).Q_Q10[last_smple_idx as usize] >> 10 - 1) + 1 >> 1 + }) as i8; + *pxq.offset((i - decisionDelay) as isize) = (if (if 8 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 * Gain_Q10 as i64 >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) as i16; + (*NSQ).sLTP_shp_Q14[((*NSQ).sLTP_shp_buf_idx - decisionDelay + i) as usize] = + (*psDD).Shape_Q14[last_smple_idx as usize]; + i += 1; + } + memcpy( + ((*NSQ).sLPC_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psDD).sLPC_Q14) + .as_mut_ptr() + .offset((*psEncC).subfr_length as isize) as *mut i32 + as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*NSQ).sAR2_Q14).as_mut_ptr() as *mut core::ffi::c_void, + ((*psDD).sAR2_Q14).as_mut_ptr() as *const core::ffi::c_void, + ::core::mem::size_of::<[i32; 24]>() as u64, + ); + (*NSQ).sLF_AR_shp_Q14 = (*psDD).LF_AR_Q14; + (*NSQ).sDiff_shp_Q14 = (*psDD).Diff_Q14; + (*NSQ).lagPrev = *pitchL.offset(((*psEncC).nb_subfr - 1) as isize); + memmove( + ((*NSQ).xq).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*NSQ).xq) + .as_mut_ptr() + .offset((*psEncC).frame_length as isize) as *mut i16 + as *const core::ffi::c_void, + ((*psEncC).ltp_mem_length as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + memmove( + ((*NSQ).sLTP_shp_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*NSQ).sLTP_shp_Q14) + .as_mut_ptr() + .offset((*psEncC).frame_length as isize) as *mut i32 + as *const core::ffi::c_void, + ((*psEncC).ltp_mem_length as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); +} +#[inline] +unsafe fn silk_noise_shape_quantizer_del_dec( + NSQ: *mut silk_nsq_state, + psDelDec: *mut NSQ_del_dec_struct, + signalType: i32, + x_Q10: *const i32, + pulses: *mut i8, + xq: *mut i16, + sLTP_Q15: *mut i32, + delayedGain_Q10: *mut i32, + a_Q12: *const i16, + b_Q14: *const i16, + AR_shp_Q13: *const i16, + lag: i32, + HarmShapeFIRPacked_Q14: i32, + Tilt_Q14: i32, + LF_shp_Q14: i32, + Gain_Q16: i32, + Lambda_Q10: i32, + offset_Q10: i32, + length: i32, + subfr: i32, + shapingLPCOrder: i32, + predictLPCOrder: i32, + warping_Q16: i32, + nStatesDelayedDecision: i32, + smpl_buf_idx: *mut i32, + decisionDelay: i32, + _arch: i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + let mut Winner_ind: i32 = 0; + let mut RDmin_ind: i32 = 0; + let mut RDmax_ind: i32 = 0; + let mut last_smple_idx: i32 = 0; + let mut Winner_rand_state: i32 = 0; + let mut LTP_pred_Q14: i32 = 0; + let mut LPC_pred_Q14: i32 = 0; + let mut n_AR_Q14: i32 = 0; + let mut n_LTP_Q14: i32 = 0; + let mut n_LF_Q14: i32 = 0; + let mut r_Q10: i32 = 0; + let mut rr_Q10: i32 = 0; + let mut rd1_Q10: i32 = 0; + let mut rd2_Q10: i32 = 0; + let mut RDmin_Q10: i32 = 0; + let mut RDmax_Q10: i32 = 0; + let mut q1_Q0: i32 = 0; + let mut q1_Q10: i32 = 0; + let mut q2_Q10: i32 = 0; + let mut exc_Q14: i32 = 0; + let mut LPC_exc_Q14: i32 = 0; + let mut xq_Q14: i32 = 0; + let mut Gain_Q10: i32 = 0; + let mut tmp1: i32 = 0; + let mut tmp2: i32 = 0; + let mut sLF_AR_shp_Q14: i32 = 0; + let mut pred_lag_ptr: *mut i32 = 0 as *mut i32; + let mut shp_lag_ptr: *mut i32 = 0 as *mut i32; + let mut psLPC_Q14: *mut i32 = 0 as *mut i32; + let mut psDD: *mut NSQ_del_dec_struct = 0 as *mut NSQ_del_dec_struct; + let mut psSS: *mut NSQ_sample_struct = 0 as *mut NSQ_sample_struct; + assert!(nStatesDelayedDecision > 0); + let vla = nStatesDelayedDecision as usize; + let mut psSampleState: Vec = ::std::vec::from_elem( + [NSQ_sample_struct { + Q_Q10: 0, + RD_Q10: 0, + xq_Q14: 0, + LF_AR_Q14: 0, + Diff_Q14: 0, + sLTP_shp_Q14: 0, + LPC_exc_Q14: 0, + }; 2], + vla, + ); + shp_lag_ptr = &mut *((*NSQ).sLTP_shp_Q14) + .as_mut_ptr() + .offset(((*NSQ).sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2) as isize) + as *mut i32; + pred_lag_ptr = + &mut *sLTP_Q15.offset(((*NSQ).sLTP_buf_idx - lag + LTP_ORDER / 2) as isize) as *mut i32; + Gain_Q10 = Gain_Q16 >> 6; + i = 0; + while i < length { + if signalType == TYPE_VOICED { + LTP_pred_Q14 = 2; + LTP_pred_Q14 = (LTP_pred_Q14 as i64 + + (*pred_lag_ptr.offset(0 as isize) as i64 * *b_Q14.offset(0 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q14 = (LTP_pred_Q14 as i64 + + (*pred_lag_ptr.offset(-1 as isize) as i64 * *b_Q14.offset(1 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q14 = (LTP_pred_Q14 as i64 + + (*pred_lag_ptr.offset(-(2) as isize) as i64 * *b_Q14.offset(2 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q14 = (LTP_pred_Q14 as i64 + + (*pred_lag_ptr.offset(-(3) as isize) as i64 * *b_Q14.offset(3 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q14 = (LTP_pred_Q14 as i64 + + (*pred_lag_ptr.offset(-(4) as isize) as i64 * *b_Q14.offset(4 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q14 = ((LTP_pred_Q14 as u32) << 1) as i32; + pred_lag_ptr = pred_lag_ptr.offset(1); + } else { + LTP_pred_Q14 = 0; + } + if lag > 0 { + n_LTP_Q14 = ((*shp_lag_ptr.offset(0 as isize) + *shp_lag_ptr.offset(-(2) as isize)) + as i64 + * HarmShapeFIRPacked_Q14 as i16 as i64 + >> 16) as i32; + n_LTP_Q14 = (n_LTP_Q14 as i64 + + (*shp_lag_ptr.offset(-1 as isize) as i64 * (HarmShapeFIRPacked_Q14 as i64 >> 16) + >> 16)) as i32; + n_LTP_Q14 = LTP_pred_Q14 - ((n_LTP_Q14 as u32) << 2) as i32; + shp_lag_ptr = shp_lag_ptr.offset(1); + } else { + n_LTP_Q14 = 0; + } + k = 0; + while k < nStatesDelayedDecision { + psDD = &mut *psDelDec.offset(k as isize) as *mut NSQ_del_dec_struct; + psSS = (*psSampleState.as_mut_ptr().offset(k as isize)).as_mut_ptr(); + (*psDD).Seed = + 907633515_u32.wrapping_add(((*psDD).Seed as u32).wrapping_mul(196314165)) as i32; + psLPC_Q14 = &mut *((*psDD).sLPC_Q14) + .as_mut_ptr() + .offset((NSQ_LPC_BUF_LENGTH - 1 + i) as isize) as *mut i32; + LPC_pred_Q14 = + silk_noise_shape_quantizer_short_prediction_c(psLPC_Q14, a_Q12, predictLPCOrder); + LPC_pred_Q14 = ((LPC_pred_Q14 as u32) << 4) as i32; + assert!(shapingLPCOrder & 1 == 0); + tmp2 = ((*psDD).Diff_Q14 as i64 + + ((*psDD).sAR2_Q14[0 as usize] as i64 * warping_Q16 as i16 as i64 >> 16)) + as i32; + tmp1 = ((*psDD).sAR2_Q14[0 as usize] as i64 + + (((*psDD).sAR2_Q14[1 as usize] - tmp2) as i64 * warping_Q16 as i16 as i64 >> 16)) + as i32; + (*psDD).sAR2_Q14[0 as usize] = tmp2; + n_AR_Q14 = shapingLPCOrder >> 1; + n_AR_Q14 = (n_AR_Q14 as i64 + + (tmp2 as i64 * *AR_shp_Q13.offset(0 as isize) as i64 >> 16)) + as i32; + j = 2; + while j < shapingLPCOrder { + tmp2 = ((*psDD).sAR2_Q14[(j - 1) as usize] as i64 + + (((*psDD).sAR2_Q14[(j + 0) as usize] - tmp1) as i64 + * warping_Q16 as i16 as i64 + >> 16)) as i32; + (*psDD).sAR2_Q14[(j - 1) as usize] = tmp1; + n_AR_Q14 = (n_AR_Q14 as i64 + + (tmp1 as i64 * *AR_shp_Q13.offset((j - 1) as isize) as i64 >> 16)) + as i32; + tmp1 = ((*psDD).sAR2_Q14[(j + 0) as usize] as i64 + + (((*psDD).sAR2_Q14[(j + 1) as usize] - tmp2) as i64 + * warping_Q16 as i16 as i64 + >> 16)) as i32; + (*psDD).sAR2_Q14[(j + 0) as usize] = tmp2; + n_AR_Q14 = (n_AR_Q14 as i64 + + (tmp2 as i64 * *AR_shp_Q13.offset(j as isize) as i64 >> 16)) + as i32; + j += 2; + } + (*psDD).sAR2_Q14[(shapingLPCOrder - 1) as usize] = tmp1; + n_AR_Q14 = (n_AR_Q14 as i64 + + (tmp1 as i64 * *AR_shp_Q13.offset((shapingLPCOrder - 1) as isize) as i64 >> 16)) + as i32; + n_AR_Q14 = ((n_AR_Q14 as u32) << 1) as i32; + n_AR_Q14 = (n_AR_Q14 as i64 + ((*psDD).LF_AR_Q14 as i64 * Tilt_Q14 as i16 as i64 >> 16)) + as i32; + n_AR_Q14 = ((n_AR_Q14 as u32) << 2) as i32; + n_LF_Q14 = ((*psDD).Shape_Q14[*smpl_buf_idx as usize] as i64 * LF_shp_Q14 as i16 as i64 + >> 16) as i32; + n_LF_Q14 = (n_LF_Q14 as i64 + + ((*psDD).LF_AR_Q14 as i64 * (LF_shp_Q14 as i64 >> 16) >> 16)) + as i32; + n_LF_Q14 = ((n_LF_Q14 as u32) << 2) as i32; + tmp1 = n_AR_Q14 + n_LF_Q14; + tmp2 = n_LTP_Q14 + LPC_pred_Q14; + tmp1 = tmp2 - tmp1; + tmp1 = if 4 == 1 { + (tmp1 >> 1) + (tmp1 & 1) + } else { + (tmp1 >> 4 - 1) + 1 >> 1 + }; + r_Q10 = *x_Q10.offset(i as isize) - tmp1; + if (*psDD).Seed < 0 { + r_Q10 = -r_Q10; + } + r_Q10 = if -((31) << 10) > (30) << 10 { + if r_Q10 > -((31) << 10) { + -((31) << 10) + } else if r_Q10 < (30) << 10 { + (30) << 10 + } else { + r_Q10 + } + } else if r_Q10 > (30) << 10 { + (30) << 10 + } else if r_Q10 < -((31) << 10) { + -((31) << 10) + } else { + r_Q10 + }; + q1_Q10 = r_Q10 - offset_Q10; + q1_Q0 = q1_Q10 >> 10; + if Lambda_Q10 > 2048 { + let rdo_offset: i32 = Lambda_Q10 / 2 - 512; + if q1_Q10 > rdo_offset { + q1_Q0 = q1_Q10 - rdo_offset >> 10; + } else if q1_Q10 < -rdo_offset { + q1_Q0 = q1_Q10 + rdo_offset >> 10; + } else if q1_Q10 < 0 { + q1_Q0 = -1; + } else { + q1_Q0 = 0; + } + } + if q1_Q0 > 0 { + q1_Q10 = ((q1_Q0 as u32) << 10) as i32 - 80; + q1_Q10 = q1_Q10 + offset_Q10; + q2_Q10 = q1_Q10 + 1024; + rd1_Q10 = q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q10 = q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } else if q1_Q0 == 0 { + q1_Q10 = offset_Q10; + q2_Q10 = q1_Q10 + (1024 - 80); + rd1_Q10 = q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q10 = q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } else if q1_Q0 == -1 { + q2_Q10 = offset_Q10; + q1_Q10 = q2_Q10 - (1024 - 80); + rd1_Q10 = -q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q10 = q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } else { + q1_Q10 = ((q1_Q0 as u32) << 10) as i32 + 80; + q1_Q10 = q1_Q10 + offset_Q10; + q2_Q10 = q1_Q10 + 1024; + rd1_Q10 = -q1_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + rd2_Q10 = -q2_Q10 as i16 as i32 * Lambda_Q10 as i16 as i32; + } + rr_Q10 = r_Q10 - q1_Q10; + rd1_Q10 = rd1_Q10 + rr_Q10 as i16 as i32 * rr_Q10 as i16 as i32 >> 10; + rr_Q10 = r_Q10 - q2_Q10; + rd2_Q10 = rd2_Q10 + rr_Q10 as i16 as i32 * rr_Q10 as i16 as i32 >> 10; + if rd1_Q10 < rd2_Q10 { + (*psSS.offset(0 as isize)).RD_Q10 = (*psDD).RD_Q10 + rd1_Q10; + (*psSS.offset(1 as isize)).RD_Q10 = (*psDD).RD_Q10 + rd2_Q10; + (*psSS.offset(0 as isize)).Q_Q10 = q1_Q10; + (*psSS.offset(1 as isize)).Q_Q10 = q2_Q10; + } else { + (*psSS.offset(0 as isize)).RD_Q10 = (*psDD).RD_Q10 + rd2_Q10; + (*psSS.offset(1 as isize)).RD_Q10 = (*psDD).RD_Q10 + rd1_Q10; + (*psSS.offset(0 as isize)).Q_Q10 = q2_Q10; + (*psSS.offset(1 as isize)).Q_Q10 = q1_Q10; + } + exc_Q14 = (((*psSS.offset(0 as isize)).Q_Q10 as u32) << 4) as i32; + if (*psDD).Seed < 0 { + exc_Q14 = -exc_Q14; + } + LPC_exc_Q14 = exc_Q14 + LTP_pred_Q14; + xq_Q14 = LPC_exc_Q14 + LPC_pred_Q14; + (*psSS.offset(0 as isize)).Diff_Q14 = + xq_Q14 - ((*x_Q10.offset(i as isize) as u32) << 4) as i32; + sLF_AR_shp_Q14 = (*psSS.offset(0 as isize)).Diff_Q14 - n_AR_Q14; + (*psSS.offset(0 as isize)).sLTP_shp_Q14 = sLF_AR_shp_Q14 - n_LF_Q14; + (*psSS.offset(0 as isize)).LF_AR_Q14 = sLF_AR_shp_Q14; + (*psSS.offset(0 as isize)).LPC_exc_Q14 = LPC_exc_Q14; + (*psSS.offset(0 as isize)).xq_Q14 = xq_Q14; + exc_Q14 = (((*psSS.offset(1 as isize)).Q_Q10 as u32) << 4) as i32; + if (*psDD).Seed < 0 { + exc_Q14 = -exc_Q14; + } + LPC_exc_Q14 = exc_Q14 + LTP_pred_Q14; + xq_Q14 = LPC_exc_Q14 + LPC_pred_Q14; + (*psSS.offset(1 as isize)).Diff_Q14 = + xq_Q14 - ((*x_Q10.offset(i as isize) as u32) << 4) as i32; + sLF_AR_shp_Q14 = (*psSS.offset(1 as isize)).Diff_Q14 - n_AR_Q14; + (*psSS.offset(1 as isize)).sLTP_shp_Q14 = sLF_AR_shp_Q14 - n_LF_Q14; + (*psSS.offset(1 as isize)).LF_AR_Q14 = sLF_AR_shp_Q14; + (*psSS.offset(1 as isize)).LPC_exc_Q14 = LPC_exc_Q14; + (*psSS.offset(1 as isize)).xq_Q14 = xq_Q14; + k += 1; + } + *smpl_buf_idx = (*smpl_buf_idx - 1) % DECISION_DELAY; + if *smpl_buf_idx < 0 { + *smpl_buf_idx += DECISION_DELAY; + } + last_smple_idx = (*smpl_buf_idx + decisionDelay) % DECISION_DELAY; + RDmin_Q10 = (*psSampleState.as_mut_ptr().offset(0 as isize))[0 as usize].RD_Q10; + Winner_ind = 0; + k = 1; + while k < nStatesDelayedDecision { + if (*psSampleState.as_mut_ptr().offset(k as isize))[0 as usize].RD_Q10 < RDmin_Q10 { + RDmin_Q10 = (*psSampleState.as_mut_ptr().offset(k as isize))[0 as usize].RD_Q10; + Winner_ind = k; + } + k += 1; + } + Winner_rand_state = + (*psDelDec.offset(Winner_ind as isize)).RandState[last_smple_idx as usize]; + k = 0; + while k < nStatesDelayedDecision { + if (*psDelDec.offset(k as isize)).RandState[last_smple_idx as usize] + != Winner_rand_state + { + (*psSampleState.as_mut_ptr().offset(k as isize))[0 as usize].RD_Q10 = + (*psSampleState.as_mut_ptr().offset(k as isize))[0 as usize].RD_Q10 + + (0x7fffffff >> 4); + (*psSampleState.as_mut_ptr().offset(k as isize))[1 as usize].RD_Q10 = + (*psSampleState.as_mut_ptr().offset(k as isize))[1 as usize].RD_Q10 + + (0x7fffffff >> 4); + } + k += 1; + } + RDmax_Q10 = (*psSampleState.as_mut_ptr().offset(0 as isize))[0 as usize].RD_Q10; + RDmin_Q10 = (*psSampleState.as_mut_ptr().offset(0 as isize))[1 as usize].RD_Q10; + RDmax_ind = 0; + RDmin_ind = 0; + k = 1; + while k < nStatesDelayedDecision { + if (*psSampleState.as_mut_ptr().offset(k as isize))[0 as usize].RD_Q10 > RDmax_Q10 { + RDmax_Q10 = (*psSampleState.as_mut_ptr().offset(k as isize))[0 as usize].RD_Q10; + RDmax_ind = k; + } + if (*psSampleState.as_mut_ptr().offset(k as isize))[1 as usize].RD_Q10 < RDmin_Q10 { + RDmin_Q10 = (*psSampleState.as_mut_ptr().offset(k as isize))[1 as usize].RD_Q10; + RDmin_ind = k; + } + k += 1; + } + if RDmin_Q10 < RDmax_Q10 { + memcpy( + (&mut *psDelDec.offset(RDmax_ind as isize) as *mut NSQ_del_dec_struct as *mut i32) + .offset(i as isize) as *mut core::ffi::c_void, + (&mut *psDelDec.offset(RDmin_ind as isize) as *mut NSQ_del_dec_struct as *mut i32) + .offset(i as isize) as *const core::ffi::c_void, + (::core::mem::size_of::() as u64) + .wrapping_sub((i as u64).wrapping_mul(::core::mem::size_of::() as u64)), + ); + memcpy( + &mut *(*psSampleState.as_mut_ptr().offset(RDmax_ind as isize)) + .as_mut_ptr() + .offset(0 as isize) as *mut NSQ_sample_struct + as *mut core::ffi::c_void, + &mut *(*psSampleState.as_mut_ptr().offset(RDmin_ind as isize)) + .as_mut_ptr() + .offset(1 as isize) as *mut NSQ_sample_struct + as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + } + psDD = &mut *psDelDec.offset(Winner_ind as isize) as *mut NSQ_del_dec_struct; + if subfr > 0 || i >= decisionDelay { + *pulses.offset((i - decisionDelay) as isize) = (if 10 == 1 { + ((*psDD).Q_Q10[last_smple_idx as usize] >> 1) + + ((*psDD).Q_Q10[last_smple_idx as usize] & 1) + } else { + ((*psDD).Q_Q10[last_smple_idx as usize] >> 10 - 1) + 1 >> 1 + }) as i8; + *xq.offset((i - decisionDelay) as isize) = (if (if 8 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + >> 1) + + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + & 1) + } else { + (((*psDD).Xq_Q14[last_smple_idx as usize] as i64 + * *delayedGain_Q10.offset(last_smple_idx as isize) as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) as i16; + (*NSQ).sLTP_shp_Q14[((*NSQ).sLTP_shp_buf_idx - decisionDelay) as usize] = + (*psDD).Shape_Q14[last_smple_idx as usize]; + *sLTP_Q15.offset(((*NSQ).sLTP_buf_idx - decisionDelay) as isize) = + (*psDD).Pred_Q15[last_smple_idx as usize]; + } + (*NSQ).sLTP_shp_buf_idx += 1; + (*NSQ).sLTP_buf_idx += 1; + k = 0; + while k < nStatesDelayedDecision { + psDD = &mut *psDelDec.offset(k as isize) as *mut NSQ_del_dec_struct; + psSS = &mut *(*psSampleState.as_mut_ptr().offset(k as isize)) + .as_mut_ptr() + .offset(0 as isize) as *mut NSQ_sample_struct; + (*psDD).LF_AR_Q14 = (*psSS).LF_AR_Q14; + (*psDD).Diff_Q14 = (*psSS).Diff_Q14; + (*psDD).sLPC_Q14[(NSQ_LPC_BUF_LENGTH + i) as usize] = (*psSS).xq_Q14; + (*psDD).Xq_Q14[*smpl_buf_idx as usize] = (*psSS).xq_Q14; + (*psDD).Q_Q10[*smpl_buf_idx as usize] = (*psSS).Q_Q10; + (*psDD).Pred_Q15[*smpl_buf_idx as usize] = (((*psSS).LPC_exc_Q14 as u32) << 1) as i32; + (*psDD).Shape_Q14[*smpl_buf_idx as usize] = (*psSS).sLTP_shp_Q14; + (*psDD).Seed = ((*psDD).Seed as u32).wrapping_add( + (if 10 == 1 { + ((*psSS).Q_Q10 >> 1) + ((*psSS).Q_Q10 & 1) + } else { + ((*psSS).Q_Q10 >> 10 - 1) + 1 >> 1 + }) as u32, + ) as i32; + (*psDD).RandState[*smpl_buf_idx as usize] = (*psDD).Seed; + (*psDD).RD_Q10 = (*psSS).RD_Q10; + k += 1; + } + *delayedGain_Q10.offset(*smpl_buf_idx as isize) = Gain_Q10; + i += 1; + } + k = 0; + while k < nStatesDelayedDecision { + psDD = &mut *psDelDec.offset(k as isize) as *mut NSQ_del_dec_struct; + memcpy( + ((*psDD).sLPC_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psDD).sLPC_Q14).as_mut_ptr().offset(length as isize) as *mut i32 + as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + k += 1; + } +} +#[inline] +unsafe fn silk_nsq_del_dec_scale_states( + psEncC: *const silk_encoder_state, + NSQ: *mut silk_nsq_state, + psDelDec: *mut NSQ_del_dec_struct, + x16: *const i16, + x_sc_Q10: *mut i32, + sLTP: *const i16, + sLTP_Q15: *mut i32, + subfr: i32, + nStatesDelayedDecision: i32, + LTP_scale_Q14: i32, + Gains_Q16: *const i32, + pitchL: *const i32, + signal_type: i32, + decisionDelay: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut lag: i32 = 0; + let mut gain_adj_Q16: i32 = 0; + let mut inv_gain_Q31: i32 = 0; + let mut inv_gain_Q26: i32 = 0; + let mut psDD: *mut NSQ_del_dec_struct = 0 as *mut NSQ_del_dec_struct; + lag = *pitchL.offset(subfr as isize); + inv_gain_Q31 = silk_INVERSE32_varQ( + if *Gains_Q16.offset(subfr as isize) > 1 { + *Gains_Q16.offset(subfr as isize) + } else { + 1 + }, + 47, + ); + inv_gain_Q26 = if 5 == 1 { + (inv_gain_Q31 >> 1) + (inv_gain_Q31 & 1) + } else { + (inv_gain_Q31 >> 5 - 1) + 1 >> 1 + }; + i = 0; + while i < (*psEncC).subfr_length { + *x_sc_Q10.offset(i as isize) = + (*x16.offset(i as isize) as i64 * inv_gain_Q26 as i64 >> 16) as i32; + i += 1; + } + if (*NSQ).rewhite_flag != 0 { + if subfr == 0 { + inv_gain_Q31 = (((inv_gain_Q31 as i64 * LTP_scale_Q14 as i16 as i64 >> 16) as i32 + as u32) + << 2) as i32; + } + i = (*NSQ).sLTP_buf_idx - lag - LTP_ORDER / 2; + while i < (*NSQ).sLTP_buf_idx { + *sLTP_Q15.offset(i as isize) = + (inv_gain_Q31 as i64 * *sLTP.offset(i as isize) as i64 >> 16) as i32; + i += 1; + } + } + if *Gains_Q16.offset(subfr as isize) != (*NSQ).prev_gain_Q16 { + gain_adj_Q16 = silk_DIV32_varQ((*NSQ).prev_gain_Q16, *Gains_Q16.offset(subfr as isize), 16); + i = (*NSQ).sLTP_shp_buf_idx - (*psEncC).ltp_mem_length; + while i < (*NSQ).sLTP_shp_buf_idx { + (*NSQ).sLTP_shp_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*NSQ).sLTP_shp_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + if signal_type == TYPE_VOICED && (*NSQ).rewhite_flag == 0 { + i = (*NSQ).sLTP_buf_idx - lag - LTP_ORDER / 2; + while i < (*NSQ).sLTP_buf_idx - decisionDelay { + *sLTP_Q15.offset(i as isize) = + (gain_adj_Q16 as i64 * *sLTP_Q15.offset(i as isize) as i64 >> 16) as i32; + i += 1; + } + } + k = 0; + while k < nStatesDelayedDecision { + psDD = &mut *psDelDec.offset(k as isize) as *mut NSQ_del_dec_struct; + (*psDD).LF_AR_Q14 = (gain_adj_Q16 as i64 * (*psDD).LF_AR_Q14 as i64 >> 16) as i32; + (*psDD).Diff_Q14 = (gain_adj_Q16 as i64 * (*psDD).Diff_Q14 as i64 >> 16) as i32; + i = 0; + while i < NSQ_LPC_BUF_LENGTH { + (*psDD).sLPC_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*psDD).sLPC_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + i = 0; + while i < MAX_SHAPE_LPC_ORDER { + (*psDD).sAR2_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*psDD).sAR2_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + i = 0; + while i < DECISION_DELAY { + (*psDD).Pred_Q15[i as usize] = + (gain_adj_Q16 as i64 * (*psDD).Pred_Q15[i as usize] as i64 >> 16) as i32; + (*psDD).Shape_Q14[i as usize] = + (gain_adj_Q16 as i64 * (*psDD).Shape_Q14[i as usize] as i64 >> 16) as i32; + i += 1; + } + k += 1; + } + (*NSQ).prev_gain_Q16 = *Gains_Q16.offset(subfr as isize); + } +} diff --git a/vendor/unsafe-libopus/src/silk/PLC.rs b/vendor/unsafe-libopus/src/silk/PLC.rs new file mode 100644 index 00000000..94ebf9cc --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/PLC.rs @@ -0,0 +1,814 @@ +pub const RAND_BUF_MASK: i32 = RAND_BUF_SIZE - 1; +pub const RAND_BUF_SIZE: i32 = 128; +pub const V_PITCH_GAIN_START_MIN_Q14: i32 = 11469; +pub const V_PITCH_GAIN_START_MAX_Q14: i32 = 15565; +pub mod typedef_h { + pub const silk_int32_MIN: i32 = i32::MIN; + pub const silk_int32_MAX: i32 = i32::MAX; + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int16_MIN: i32 = i16::MIN as i32; +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN, silk_int32_MAX, silk_int32_MIN}; +use crate::externs::{memcpy, memset}; +use crate::silk::bwexpander::silk_bwexpander; +use crate::silk::define::{ + LTP_ORDER, MAX_LPC_ORDER, MAX_NB_SUBFR, TYPE_NO_VOICE_ACTIVITY, TYPE_VOICED, +}; +use crate::silk::macros::silk_CLZ32; +use crate::silk::structs::{silk_PLC_struct, silk_decoder_control, silk_decoder_state}; +use crate::silk::sum_sqr_shift::silk_sum_sqr_shift; +use crate::silk::Inlines::{silk_INVERSE32_varQ, silk_SQRT_APPROX}; +use crate::silk::LPC_analysis_filter::silk_LPC_analysis_filter; +use crate::silk::LPC_inv_pred_gain::silk_LPC_inverse_pred_gain_c; +use crate::silk::SigProc_FIX::{silk_max_16, silk_max_32, silk_max_int, silk_min_32, silk_min_int}; + +pub const NB_ATT: i32 = 2; +static mut HARM_ATT_Q15: [i16; 2] = [32440, 31130]; +static mut PLC_RAND_ATTENUATE_V_Q15: [i16; 2] = [31130, 26214]; +static mut PLC_RAND_ATTENUATE_UV_Q15: [i16; 2] = [32440, 29491]; +pub unsafe fn silk_PLC_Reset(psDec: *mut silk_decoder_state) { + (*psDec).sPLC.pitchL_Q8 = (((*psDec).frame_length as u32) << 8 - 1) as i32; + (*psDec).sPLC.prevGain_Q16[0 as usize] = ((1 * ((1) << 16)) as f64 + 0.5f64) as i32; + (*psDec).sPLC.prevGain_Q16[1 as usize] = ((1 * ((1) << 16)) as f64 + 0.5f64) as i32; + (*psDec).sPLC.subfr_length = 20; + (*psDec).sPLC.nb_subfr = 2; +} +pub unsafe fn silk_PLC( + psDec: *mut silk_decoder_state, + psDecCtrl: *mut silk_decoder_control, + frame: *mut i16, + lost: i32, + arch: i32, +) { + if (*psDec).fs_kHz != (*psDec).sPLC.fs_kHz { + silk_PLC_Reset(psDec); + (*psDec).sPLC.fs_kHz = (*psDec).fs_kHz; + } + if lost != 0 { + silk_PLC_conceal(psDec, psDecCtrl, frame, arch); + (*psDec).lossCnt += 1; + } else { + silk_PLC_update(psDec, psDecCtrl); + }; +} +#[inline] +unsafe fn silk_PLC_update(psDec: *mut silk_decoder_state, psDecCtrl: *mut silk_decoder_control) { + let mut LTP_Gain_Q14: i32 = 0; + let mut temp_LTP_Gain_Q14: i32 = 0; + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut psPLC: *mut silk_PLC_struct = 0 as *mut silk_PLC_struct; + psPLC = &mut (*psDec).sPLC; + (*psDec).prevSignalType = (*psDec).indices.signalType as i32; + LTP_Gain_Q14 = 0; + if (*psDec).indices.signalType as i32 == TYPE_VOICED { + j = 0; + while j * (*psDec).subfr_length < (*psDecCtrl).pitchL[((*psDec).nb_subfr - 1) as usize] { + if j == (*psDec).nb_subfr { + break; + } + temp_LTP_Gain_Q14 = 0; + i = 0; + while i < LTP_ORDER { + temp_LTP_Gain_Q14 += (*psDecCtrl).LTPCoef_Q14 + [(((*psDec).nb_subfr - 1 - j) * LTP_ORDER + i) as usize] + as i32; + i += 1; + } + if temp_LTP_Gain_Q14 > LTP_Gain_Q14 { + LTP_Gain_Q14 = temp_LTP_Gain_Q14; + memcpy( + ((*psPLC).LTPCoef_Q14).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psDecCtrl).LTPCoef_Q14) + .as_mut_ptr() + .offset((((*psDec).nb_subfr - 1 - j) as i16 as i32 * 5) as isize) + as *mut i16 as *const core::ffi::c_void, + 5_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psPLC).pitchL_Q8 = (((*psDecCtrl).pitchL[((*psDec).nb_subfr - 1 - j) as usize] + as u32) + << 8) as i32; + } + j += 1; + } + memset( + ((*psPLC).LTPCoef_Q14).as_mut_ptr() as *mut core::ffi::c_void, + 0, + 5_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psPLC).LTPCoef_Q14[(LTP_ORDER / 2) as usize] = LTP_Gain_Q14 as i16; + if LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 { + let mut scale_Q10: i32 = 0; + let mut tmp: i32 = 0; + tmp = ((11469) << 10) as i32; + scale_Q10 = tmp / (if LTP_Gain_Q14 > 1 { LTP_Gain_Q14 } else { 1 }); + i = 0; + while i < LTP_ORDER { + (*psPLC).LTPCoef_Q14[i as usize] = ((*psPLC).LTPCoef_Q14[i as usize] as i32 + * scale_Q10 as i16 as i32 + >> 10) as i16; + i += 1; + } + } else if LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 { + let mut scale_Q14: i32 = 0; + let mut tmp_0: i32 = 0; + tmp_0 = ((15565) << 14) as i32; + scale_Q14 = tmp_0 / (if LTP_Gain_Q14 > 1 { LTP_Gain_Q14 } else { 1 }); + i = 0; + while i < LTP_ORDER { + (*psPLC).LTPCoef_Q14[i as usize] = ((*psPLC).LTPCoef_Q14[i as usize] as i32 + * scale_Q14 as i16 as i32 + >> 14) as i16; + i += 1; + } + } + } else { + (*psPLC).pitchL_Q8 = ((((*psDec).fs_kHz as i16 as i32 * 18) as u32) << 8) as i32; + memset( + ((*psPLC).LTPCoef_Q14).as_mut_ptr() as *mut core::ffi::c_void, + 0, + 5_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } + memcpy( + ((*psPLC).prevLPC_Q12).as_mut_ptr() as *mut core::ffi::c_void, + ((*psDecCtrl).PredCoef_Q12[1 as usize]).as_mut_ptr() as *const core::ffi::c_void, + ((*psDec).LPC_order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psPLC).prevLTP_scale_Q14 = (*psDecCtrl).LTP_scale_Q14 as i16; + memcpy( + ((*psPLC).prevGain_Q16).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psDecCtrl).Gains_Q16) + .as_mut_ptr() + .offset(((*psDec).nb_subfr - 2) as isize) as *mut i32 + as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psPLC).subfr_length = (*psDec).subfr_length; + (*psPLC).nb_subfr = (*psDec).nb_subfr; +} +#[inline] +unsafe fn silk_PLC_energy( + energy1: *mut i32, + shift1: *mut i32, + energy2: *mut i32, + shift2: *mut i32, + exc_Q14: *const i32, + prevGain_Q10: *const i32, + subfr_length: i32, + nb_subfr: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut exc_buf_ptr: *mut i16 = 0 as *mut i16; + let vla = (2 * subfr_length) as usize; + let mut exc_buf: Vec = ::std::vec::from_elem(0, vla); + exc_buf_ptr = exc_buf.as_mut_ptr(); + k = 0; + while k < 2 { + i = 0; + while i < subfr_length { + *exc_buf_ptr.offset(i as isize) = (if (*exc_Q14 + .offset((i + (k + nb_subfr - 2) * subfr_length) as isize) + as i64 + * *prevGain_Q10.offset(k as isize) as i64 + >> 16) as i32 + >> 8 + > silk_int16_MAX + { + silk_int16_MAX + } else if ((*exc_Q14.offset((i + (k + nb_subfr - 2) * subfr_length) as isize) as i64 + * *prevGain_Q10.offset(k as isize) as i64 + >> 16) as i32 + >> 8) + < silk_int16_MIN + { + silk_int16_MIN + } else { + (*exc_Q14.offset((i + (k + nb_subfr - 2) * subfr_length) as isize) as i64 + * *prevGain_Q10.offset(k as isize) as i64 + >> 16) as i32 + >> 8 + }) as i16; + i += 1; + } + exc_buf_ptr = exc_buf_ptr.offset(subfr_length as isize); + k += 1; + } + silk_sum_sqr_shift(energy1, shift1, exc_buf.as_mut_ptr(), subfr_length); + silk_sum_sqr_shift( + energy2, + shift2, + &mut *exc_buf.as_mut_ptr().offset(subfr_length as isize), + subfr_length, + ); +} +#[inline] +unsafe fn silk_PLC_conceal( + psDec: *mut silk_decoder_state, + psDecCtrl: *mut silk_decoder_control, + frame: *mut i16, + arch: i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + let mut lag: i32 = 0; + let mut idx: i32 = 0; + let mut sLTP_buf_idx: i32 = 0; + let mut shift1: i32 = 0; + let mut shift2: i32 = 0; + let mut rand_seed: i32 = 0; + let mut harm_Gain_Q15: i32 = 0; + let mut rand_Gain_Q15: i32 = 0; + let mut inv_gain_Q30: i32 = 0; + let mut energy1: i32 = 0; + let mut energy2: i32 = 0; + let mut rand_ptr: *mut i32 = 0 as *mut i32; + let mut pred_lag_ptr: *mut i32 = 0 as *mut i32; + let mut LPC_pred_Q10: i32 = 0; + let mut LTP_pred_Q12: i32 = 0; + let mut rand_scale_Q14: i16 = 0; + let mut B_Q14: *mut i16 = 0 as *mut i16; + let mut sLPC_Q14_ptr: *mut i32 = 0 as *mut i32; + let mut A_Q12: [i16; 16] = [0; 16]; + let psPLC: *mut silk_PLC_struct = &mut (*psDec).sPLC; + let mut prevGain_Q10: [i32; 2] = [0; 2]; + let vla = ((*psDec).ltp_mem_length + (*psDec).frame_length) as usize; + let mut sLTP_Q14: Vec = ::std::vec::from_elem(0, vla); + let vla_0 = (*psDec).ltp_mem_length as usize; + let mut sLTP: Vec = ::std::vec::from_elem(0, vla_0); + prevGain_Q10[0 as usize] = (*psPLC).prevGain_Q16[0 as usize] >> 6; + prevGain_Q10[1 as usize] = (*psPLC).prevGain_Q16[1 as usize] >> 6; + if (*psDec).first_frame_after_reset != 0 { + memset( + ((*psPLC).prevLPC_Q12).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 16]>() as u64, + ); + } + silk_PLC_energy( + &mut energy1, + &mut shift1, + &mut energy2, + &mut shift2, + ((*psDec).exc_Q14).as_mut_ptr(), + prevGain_Q10.as_mut_ptr(), + (*psDec).subfr_length, + (*psDec).nb_subfr, + ); + if energy1 >> shift2 < energy2 >> shift1 { + rand_ptr = &mut *((*psDec).exc_Q14).as_mut_ptr().offset((silk_max_int + as unsafe fn(i32, i32) -> i32)( + 0, + ((*psPLC).nb_subfr - 1) * (*psPLC).subfr_length - RAND_BUF_SIZE, + ) as isize) as *mut i32; + } else { + rand_ptr = &mut *((*psDec).exc_Q14).as_mut_ptr().offset((silk_max_int + as unsafe fn(i32, i32) -> i32)( + 0, + (*psPLC).nb_subfr * (*psPLC).subfr_length - RAND_BUF_SIZE, + ) as isize) as *mut i32; + } + B_Q14 = ((*psPLC).LTPCoef_Q14).as_mut_ptr(); + rand_scale_Q14 = (*psPLC).randScale_Q14; + harm_Gain_Q15 = HARM_ATT_Q15[silk_min_int(NB_ATT - 1, (*psDec).lossCnt) as usize] as i32; + if (*psDec).prevSignalType == TYPE_VOICED { + rand_Gain_Q15 = + PLC_RAND_ATTENUATE_V_Q15[silk_min_int(NB_ATT - 1, (*psDec).lossCnt) as usize] as i32; + } else { + rand_Gain_Q15 = + PLC_RAND_ATTENUATE_UV_Q15[silk_min_int(NB_ATT - 1, (*psDec).lossCnt) as usize] as i32; + } + silk_bwexpander( + ((*psPLC).prevLPC_Q12).as_mut_ptr(), + (*psDec).LPC_order, + (0.99f64 * ((1) << 16) as f64 + 0.5f64) as i32, + ); + memcpy( + A_Q12.as_mut_ptr() as *mut core::ffi::c_void, + ((*psPLC).prevLPC_Q12).as_mut_ptr() as *const core::ffi::c_void, + ((*psDec).LPC_order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + if (*psDec).lossCnt == 0 { + rand_scale_Q14 = ((1) << 14) as i16; + if (*psDec).prevSignalType == TYPE_VOICED { + i = 0; + while i < LTP_ORDER { + rand_scale_Q14 = (rand_scale_Q14 as i32 - *B_Q14.offset(i as isize) as i32) as i16; + i += 1; + } + rand_scale_Q14 = silk_max_16(3277, rand_scale_Q14); + rand_scale_Q14 = + (rand_scale_Q14 as i32 * (*psPLC).prevLTP_scale_Q14 as i32 >> 14) as i16; + } else { + let mut invGain_Q30: i32 = 0; + let mut down_scale_Q30: i32 = 0; + invGain_Q30 = silk_LPC_inverse_pred_gain_c( + ((*psPLC).prevLPC_Q12).as_mut_ptr(), + (*psDec).LPC_order, + ); + down_scale_Q30 = silk_min_32((1) << 30 >> 3, invGain_Q30); + down_scale_Q30 = silk_max_32((1) << 30 >> 8, down_scale_Q30); + down_scale_Q30 = ((down_scale_Q30 as u32) << 3) as i32; + rand_Gain_Q15 = + (down_scale_Q30 as i64 * rand_Gain_Q15 as i16 as i64 >> 16) as i32 >> 14; + } + } + rand_seed = (*psPLC).rand_seed; + lag = if 8 == 1 { + ((*psPLC).pitchL_Q8 >> 1) + ((*psPLC).pitchL_Q8 & 1) + } else { + ((*psPLC).pitchL_Q8 >> 8 - 1) + 1 >> 1 + }; + sLTP_buf_idx = (*psDec).ltp_mem_length; + idx = (*psDec).ltp_mem_length - lag - (*psDec).LPC_order - LTP_ORDER / 2; + assert!(idx > 0); + silk_LPC_analysis_filter( + &mut *sLTP.as_mut_ptr().offset(idx as isize), + &mut *((*psDec).outBuf).as_mut_ptr().offset(idx as isize), + A_Q12.as_mut_ptr(), + (*psDec).ltp_mem_length - idx, + (*psDec).LPC_order, + arch, + ); + inv_gain_Q30 = silk_INVERSE32_varQ((*psPLC).prevGain_Q16[1 as usize], 46); + inv_gain_Q30 = if inv_gain_Q30 < 0x7fffffff >> 1 { + inv_gain_Q30 + } else { + 0x7fffffff >> 1 + }; + i = idx + (*psDec).LPC_order; + while i < (*psDec).ltp_mem_length { + *sLTP_Q14.as_mut_ptr().offset(i as isize) = + (inv_gain_Q30 as i64 * *sLTP.as_mut_ptr().offset(i as isize) as i64 >> 16) as i32; + i += 1; + } + k = 0; + while k < (*psDec).nb_subfr { + pred_lag_ptr = &mut *sLTP_Q14 + .as_mut_ptr() + .offset((sLTP_buf_idx - lag + LTP_ORDER / 2) as isize) + as *mut i32; + i = 0; + while i < (*psDec).subfr_length { + LTP_pred_Q12 = 2; + LTP_pred_Q12 = (LTP_pred_Q12 as i64 + + (*pred_lag_ptr.offset(0 as isize) as i64 * *B_Q14.offset(0 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q12 = (LTP_pred_Q12 as i64 + + (*pred_lag_ptr.offset(-1 as isize) as i64 * *B_Q14.offset(1 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q12 = (LTP_pred_Q12 as i64 + + (*pred_lag_ptr.offset(-(2) as isize) as i64 * *B_Q14.offset(2 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q12 = (LTP_pred_Q12 as i64 + + (*pred_lag_ptr.offset(-(3) as isize) as i64 * *B_Q14.offset(3 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q12 = (LTP_pred_Q12 as i64 + + (*pred_lag_ptr.offset(-(4) as isize) as i64 * *B_Q14.offset(4 as isize) as i64 + >> 16)) as i32; + pred_lag_ptr = pred_lag_ptr.offset(1); + rand_seed = + 907633515_u32.wrapping_add((rand_seed as u32).wrapping_mul(196314165)) as i32; + idx = rand_seed >> 25 & RAND_BUF_MASK; + *sLTP_Q14.as_mut_ptr().offset(sLTP_buf_idx as isize) = (((LTP_pred_Q12 as i64 + + (*rand_ptr.offset(idx as isize) as i64 * rand_scale_Q14 as i64 >> 16)) + as i32 as u32) + << 2) as i32; + sLTP_buf_idx += 1; + i += 1; + } + j = 0; + while j < LTP_ORDER { + *B_Q14.offset(j as isize) = + (harm_Gain_Q15 as i16 as i32 * *B_Q14.offset(j as isize) as i32 >> 15) as i16; + j += 1; + } + if (*psDec).indices.signalType as i32 != TYPE_NO_VOICE_ACTIVITY { + rand_scale_Q14 = (rand_scale_Q14 as i32 * rand_Gain_Q15 as i16 as i32 >> 15) as i16; + } + (*psPLC).pitchL_Q8 = + ((*psPLC).pitchL_Q8 as i64 + ((*psPLC).pitchL_Q8 as i64 * 655 as i64 >> 16)) as i32; + (*psPLC).pitchL_Q8 = silk_min_32( + (*psPLC).pitchL_Q8, + (((18 * (*psDec).fs_kHz as i16 as i32) as u32) << 8) as i32, + ); + lag = if 8 == 1 { + ((*psPLC).pitchL_Q8 >> 1) + ((*psPLC).pitchL_Q8 & 1) + } else { + ((*psPLC).pitchL_Q8 >> 8 - 1) + 1 >> 1 + }; + k += 1; + } + sLPC_Q14_ptr = &mut *sLTP_Q14 + .as_mut_ptr() + .offset(((*psDec).ltp_mem_length - MAX_LPC_ORDER) as isize) as *mut i32; + memcpy( + sLPC_Q14_ptr as *mut core::ffi::c_void, + ((*psDec).sLPC_Q14_buf).as_mut_ptr() as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + assert!((*psDec).LPC_order >= 10); + i = 0; + while i < (*psDec).frame_length { + LPC_pred_Q10 = (*psDec).LPC_order >> 1; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 1) as isize) as i64 * A_Q12[0 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 2) as isize) as i64 * A_Q12[1 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 3) as isize) as i64 * A_Q12[2 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 4) as isize) as i64 * A_Q12[3 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 5) as isize) as i64 * A_Q12[4 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 6) as isize) as i64 * A_Q12[5 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 7) as isize) as i64 * A_Q12[6 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 8) as isize) as i64 * A_Q12[7 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 9) as isize) as i64 * A_Q12[8 as usize] as i64 >> 16)) + as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - 10) as isize) as i64 * A_Q12[9 as usize] as i64 + >> 16)) as i32; + j = 10; + while j < (*psDec).LPC_order { + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14_ptr.offset((16 + i - j - 1) as isize) as i64 + * A_Q12[j as usize] as i64 + >> 16)) as i32; + j += 1; + } + *sLPC_Q14_ptr.offset((MAX_LPC_ORDER + i) as isize) = + if (*sLPC_Q14_ptr.offset((16 + i) as isize) as u32).wrapping_add( + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if (*sLPC_Q14_ptr.offset((16 + i) as isize) + & (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32) as u32 + & 0x80000000 as u32 + != 0 + { + silk_int32_MIN as i32 + } else { + *sLPC_Q14_ptr.offset((16 + i) as isize) + + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 + } + } else if (*sLPC_Q14_ptr.offset((16 + i) as isize) + | (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32) as u32 + & 0x80000000 as u32 + == 0 + { + silk_int32_MAX + } else { + *sLPC_Q14_ptr.offset((16 + i) as isize) + + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 + }; + *frame.offset(i as isize) = (if (if (if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > 0x7fff + { + 0x7fff + } else { + if (if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < -0x8000 // tinyclient patch: silk_int16_MIN is -32768, not 0x8000 + { + -0x8000 + } else { + if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + } + } + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if (if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > 0x7fff + { + 0x7fff + } else { + if (if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < -0x8000 // tinyclient patch: silk_int16_MIN is -32768, not 0x8000 + { + -0x8000 + } else { + if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + } + } + }) < silk_int16_MIN + { + silk_int16_MIN + } else if (if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) > 0x7fff + { + 0x7fff + } else if (if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) < -0x8000 // tinyclient patch: silk_int16_MIN is -32768, not 0x8000 + { + -0x8000 + } else if 8 == 1 { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 1) + + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 + * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14_ptr.offset((16 + i) as isize) as i64 * prevGain_Q10[1 as usize] as i64 + >> 16) as i32 + >> 8 - 1) + + 1 + >> 1 + }) as i16; + i += 1; + } + memcpy( + ((*psDec).sLPC_Q14_buf).as_mut_ptr() as *mut core::ffi::c_void, + &mut *sLPC_Q14_ptr.offset((*psDec).frame_length as isize) as *mut i32 + as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psPLC).rand_seed = rand_seed; + (*psPLC).randScale_Q14 = rand_scale_Q14; + i = 0; + while i < MAX_NB_SUBFR { + (*psDecCtrl).pitchL[i as usize] = lag; + i += 1; + } +} +pub unsafe fn silk_PLC_glue_frames(psDec: *mut silk_decoder_state, frame: *mut i16, length: i32) { + let mut i: i32 = 0; + let mut energy_shift: i32 = 0; + let mut energy: i32 = 0; + let mut psPLC: *mut silk_PLC_struct = 0 as *mut silk_PLC_struct; + psPLC = &mut (*psDec).sPLC; + if (*psDec).lossCnt != 0 { + silk_sum_sqr_shift( + &mut (*psPLC).conc_energy, + &mut (*psPLC).conc_energy_shift, + frame as *const i16, + length, + ); + (*psPLC).last_frame_lost = 1; + } else { + if (*psDec).sPLC.last_frame_lost != 0 { + silk_sum_sqr_shift(&mut energy, &mut energy_shift, frame as *const i16, length); + if energy_shift > (*psPLC).conc_energy_shift { + (*psPLC).conc_energy = + (*psPLC).conc_energy >> energy_shift - (*psPLC).conc_energy_shift; + } else if energy_shift < (*psPLC).conc_energy_shift { + energy = energy >> (*psPLC).conc_energy_shift - energy_shift; + } + if energy > (*psPLC).conc_energy { + let mut frac_Q24: i32 = 0; + let mut LZ: i32 = 0; + let mut gain_Q16: i32 = 0; + let mut slope_Q16: i32 = 0; + LZ = silk_CLZ32((*psPLC).conc_energy); + LZ = LZ - 1; + (*psPLC).conc_energy = (((*psPLC).conc_energy as u32) << LZ) as i32; + energy = energy >> silk_max_32(24 - LZ, 0); + frac_Q24 = (*psPLC).conc_energy / (if energy > 1 { energy } else { 1 }); + gain_Q16 = ((silk_SQRT_APPROX(frac_Q24) as u32) << 4) as i32; + slope_Q16 = (((1) << 16) - gain_Q16) / length; + slope_Q16 = ((slope_Q16 as u32) << 2) as i32; + i = 0; + while i < length { + *frame.offset(i as isize) = + (gain_Q16 as i64 * *frame.offset(i as isize) as i64 >> 16) as i32 as i16; + gain_Q16 += slope_Q16; + if gain_Q16 > (1) << 16 { + break; + } + i += 1; + } + } + } + (*psPLC).last_frame_lost = 0; + }; +} diff --git a/vendor/unsafe-libopus/src/silk/SigProc_FIX.rs b/vendor/unsafe-libopus/src/silk/SigProc_FIX.rs new file mode 100644 index 00000000..04542181 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/SigProc_FIX.rs @@ -0,0 +1,36 @@ +#[inline] +pub fn silk_ROR32(a32: i32, rot: i32) -> i32 { + let x: u32 = a32 as u32; + let r: u32 = rot as u32; + let m: u32 = -rot as u32; + if rot == 0 { + return a32; + } else if rot < 0 { + return (x << m | x >> (32u32).wrapping_sub(m)) as i32; + } else { + return (x << (32u32).wrapping_sub(r) | x >> r) as i32; + }; +} + +#[inline] +pub fn silk_max_16(a: i16, b: i16) -> i16 { + a.max(b) +} + +#[inline] +pub fn silk_min_32(a: i32, b: i32) -> i32 { + a.min(b) +} +#[inline] +pub fn silk_max_32(a: i32, b: i32) -> i32 { + a.max(b) +} + +#[inline] +pub fn silk_min_int(a: i32, b: i32) -> i32 { + a.min(b) +} +#[inline] +pub fn silk_max_int(a: i32, b: i32) -> i32 { + a.max(b) +} diff --git a/vendor/unsafe-libopus/src/silk/VAD.rs b/vendor/unsafe-libopus/src/silk/VAD.rs new file mode 100644 index 00000000..3aaf2c17 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/VAD.rs @@ -0,0 +1,282 @@ +pub mod typedef_h { + pub const silk_uint8_MAX: i32 = 0xff; + pub const silk_int32_MAX: i32 = i32::MAX; +} +pub use self::typedef_h::{silk_int32_MAX, silk_uint8_MAX}; +use crate::externs::memset; +use crate::silk::ana_filt_bank_1::silk_ana_filt_bank_1; +use crate::silk::define::{ + VAD_INTERNAL_SUBFRAMES, VAD_NEGATIVE_OFFSET_Q5, VAD_NOISE_LEVEL_SMOOTH_COEF_Q16, VAD_N_BANDS, +}; +use crate::silk::lin2log::silk_lin2log; +use crate::silk::sigm_Q15::silk_sigm_Q15; +use crate::silk::structs::{silk_VAD_state, silk_encoder_state}; +use crate::silk::Inlines::silk_SQRT_APPROX; +use crate::silk::SigProc_FIX::{silk_max_32, silk_max_int, silk_min_int}; + +pub unsafe fn silk_VAD_Init(psSilk_VAD: *mut silk_VAD_state) -> i32 { + let mut b: i32 = 0; + let ret: i32 = 0; + memset( + psSilk_VAD as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + b = 0; + while b < VAD_N_BANDS { + (*psSilk_VAD).NoiseLevelBias[b as usize] = silk_max_32(50 / (b + 1), 1); + b += 1; + } + b = 0; + while b < VAD_N_BANDS { + (*psSilk_VAD).NL[b as usize] = 100 * (*psSilk_VAD).NoiseLevelBias[b as usize]; + (*psSilk_VAD).inv_NL[b as usize] = 0x7fffffff / (*psSilk_VAD).NL[b as usize]; + b += 1; + } + (*psSilk_VAD).counter = 15; + b = 0; + while b < VAD_N_BANDS { + (*psSilk_VAD).NrgRatioSmth_Q8[b as usize] = 100 * 256; + b += 1; + } + return ret; +} +static mut tiltWeights: [i32; 4] = [30000, 6000, -(12000), -(12000)]; +pub unsafe fn silk_VAD_GetSA_Q8_c(psEncC: *mut silk_encoder_state, pIn: *const i16) -> i32 { + let mut SA_Q15: i32 = 0; + let mut pSNR_dB_Q7: i32 = 0; + let mut input_tilt: i32 = 0; + let mut decimated_framelength1: i32 = 0; + let mut decimated_framelength2: i32 = 0; + let mut decimated_framelength: i32 = 0; + let mut dec_subframe_length: i32 = 0; + let mut dec_subframe_offset: i32 = 0; + let mut SNR_Q7: i32 = 0; + let mut i: i32 = 0; + let mut b: i32 = 0; + let mut s: i32 = 0; + let mut sumSquared: i32 = 0; + let mut smooth_coef_Q16: i32 = 0; + let mut HPstateTmp: i16 = 0; + let mut Xnrg: [i32; 4] = [0; 4]; + let mut NrgToNoiseRatio_Q8: [i32; 4] = [0; 4]; + let mut speech_nrg: i32 = 0; + let mut x_tmp: i32 = 0; + let mut X_offset: [i32; 4] = [0; 4]; + let ret: i32 = 0; + let psSilk_VAD: *mut silk_VAD_state = &mut (*psEncC).sVAD; + assert!(5 * 4 * 16 >= (*psEncC).frame_length); + assert!((*psEncC).frame_length <= 512); + assert!((*psEncC).frame_length == 8 * ((*psEncC).frame_length >> 3)); + decimated_framelength1 = (*psEncC).frame_length >> 1; + decimated_framelength2 = (*psEncC).frame_length >> 2; + decimated_framelength = (*psEncC).frame_length >> 3; + X_offset[0 as usize] = 0; + X_offset[1 as usize] = decimated_framelength + decimated_framelength2; + X_offset[2 as usize] = X_offset[1 as usize] + decimated_framelength; + X_offset[3 as usize] = X_offset[2 as usize] + decimated_framelength2; + let vla = (X_offset[3 as usize] + decimated_framelength1) as usize; + let mut X: Vec = ::std::vec::from_elem(0, vla); + silk_ana_filt_bank_1( + pIn, + &mut *((*psSilk_VAD).AnaState).as_mut_ptr().offset(0 as isize), + X.as_mut_ptr(), + &mut *X + .as_mut_ptr() + .offset(*X_offset.as_mut_ptr().offset(3 as isize) as isize), + (*psEncC).frame_length, + ); + silk_ana_filt_bank_1( + X.as_mut_ptr(), + &mut *((*psSilk_VAD).AnaState1).as_mut_ptr().offset(0 as isize), + X.as_mut_ptr(), + &mut *X + .as_mut_ptr() + .offset(*X_offset.as_mut_ptr().offset(2 as isize) as isize), + decimated_framelength1, + ); + silk_ana_filt_bank_1( + X.as_mut_ptr(), + &mut *((*psSilk_VAD).AnaState2).as_mut_ptr().offset(0 as isize), + X.as_mut_ptr(), + &mut *X + .as_mut_ptr() + .offset(*X_offset.as_mut_ptr().offset(1 as isize) as isize), + decimated_framelength2, + ); + *X.as_mut_ptr().offset((decimated_framelength - 1) as isize) = + (*X.as_mut_ptr().offset((decimated_framelength - 1) as isize) as i32 >> 1) as i16; + HPstateTmp = *X.as_mut_ptr().offset((decimated_framelength - 1) as isize); + i = decimated_framelength - 1; + while i > 0 { + *X.as_mut_ptr().offset((i - 1) as isize) = + (*X.as_mut_ptr().offset((i - 1) as isize) as i32 >> 1) as i16; + let ref mut fresh0 = *X.as_mut_ptr().offset(i as isize); + *fresh0 = (*fresh0 as i32 - *X.as_mut_ptr().offset((i - 1) as isize) as i32) as i16; + i -= 1; + } + let ref mut fresh1 = *X.as_mut_ptr().offset(0 as isize); + *fresh1 = (*fresh1 as i32 - (*psSilk_VAD).HPstate as i32) as i16; + (*psSilk_VAD).HPstate = HPstateTmp; + b = 0; + while b < VAD_N_BANDS { + decimated_framelength = (*psEncC).frame_length >> silk_min_int(4 - b, 4 - 1); + dec_subframe_length = decimated_framelength >> 2; + dec_subframe_offset = 0; + Xnrg[b as usize] = (*psSilk_VAD).XnrgSubfr[b as usize]; + s = 0; + while s < VAD_INTERNAL_SUBFRAMES { + sumSquared = 0; + i = 0; + while i < dec_subframe_length { + x_tmp = *X + .as_mut_ptr() + .offset((X_offset[b as usize] + i + dec_subframe_offset) as isize) + as i32 + >> 3; + sumSquared = sumSquared + x_tmp as i16 as i32 * x_tmp as i16 as i32; + i += 1; + } + if s < VAD_INTERNAL_SUBFRAMES - 1 { + Xnrg[b as usize] = if (Xnrg[b as usize] as u32).wrapping_add(sumSquared as u32) + & 0x80000000 as u32 + != 0 + { + silk_int32_MAX + } else { + Xnrg[b as usize] + sumSquared + }; + } else { + Xnrg[b as usize] = if (Xnrg[b as usize] as u32) + .wrapping_add((sumSquared >> 1) as u32) + & 0x80000000 as u32 + != 0 + { + silk_int32_MAX + } else { + Xnrg[b as usize] + (sumSquared >> 1) + }; + } + dec_subframe_offset += dec_subframe_length; + s += 1; + } + (*psSilk_VAD).XnrgSubfr[b as usize] = sumSquared; + b += 1; + } + silk_VAD_GetNoiseLevels( + &mut *Xnrg.as_mut_ptr().offset(0 as isize) as *mut i32 as *const i32, + psSilk_VAD, + ); + sumSquared = 0; + input_tilt = 0; + b = 0; + while b < VAD_N_BANDS { + speech_nrg = Xnrg[b as usize] - (*psSilk_VAD).NL[b as usize]; + if speech_nrg > 0 { + if Xnrg[b as usize] as u32 & 0xff800000 as u32 == 0 { + NrgToNoiseRatio_Q8[b as usize] = + ((Xnrg[b as usize] as u32) << 8) as i32 / ((*psSilk_VAD).NL[b as usize] + 1); + } else { + NrgToNoiseRatio_Q8[b as usize] = + Xnrg[b as usize] / (((*psSilk_VAD).NL[b as usize] >> 8) + 1); + } + SNR_Q7 = silk_lin2log(NrgToNoiseRatio_Q8[b as usize]) - 8 * 128; + sumSquared = sumSquared + SNR_Q7 as i16 as i32 * SNR_Q7 as i16 as i32; + if speech_nrg < (1) << 20 { + SNR_Q7 = (((silk_SQRT_APPROX(speech_nrg) as u32) << 6) as i32 as i64 + * SNR_Q7 as i16 as i64 + >> 16) as i32; + } + input_tilt = (input_tilt as i64 + + (tiltWeights[b as usize] as i64 * SNR_Q7 as i16 as i64 >> 16)) + as i32; + } else { + NrgToNoiseRatio_Q8[b as usize] = 256; + } + b += 1; + } + sumSquared = sumSquared / 4; + pSNR_dB_Q7 = (3 * silk_SQRT_APPROX(sumSquared)) as i16 as i32; + SA_Q15 = + silk_sigm_Q15((45000 * pSNR_dB_Q7 as i16 as i64 >> 16) as i32 - VAD_NEGATIVE_OFFSET_Q5); + (*psEncC).input_tilt_Q15 = (((silk_sigm_Q15(input_tilt) - 16384) as u32) << 1) as i32; + speech_nrg = 0; + b = 0; + while b < VAD_N_BANDS { + speech_nrg += (b + 1) * (Xnrg[b as usize] - (*psSilk_VAD).NL[b as usize] >> 4); + b += 1; + } + if (*psEncC).frame_length == 20 * (*psEncC).fs_kHz { + speech_nrg = speech_nrg >> 1; + } + if speech_nrg <= 0 { + SA_Q15 = SA_Q15 >> 1; + } else if speech_nrg < 16384 { + speech_nrg = ((speech_nrg as u32) << 16) as i32; + speech_nrg = silk_SQRT_APPROX(speech_nrg); + SA_Q15 = ((32768 + speech_nrg) as i64 * SA_Q15 as i16 as i64 >> 16) as i32; + } + (*psEncC).speech_activity_Q8 = silk_min_int(SA_Q15 >> 7, silk_uint8_MAX); + smooth_coef_Q16 = + (4096 * (SA_Q15 as i64 * SA_Q15 as i16 as i64 >> 16) as i32 as i16 as i64 >> 16) as i32; + if (*psEncC).frame_length == 10 * (*psEncC).fs_kHz { + smooth_coef_Q16 >>= 1; + } + b = 0; + while b < VAD_N_BANDS { + (*psSilk_VAD).NrgRatioSmth_Q8[b as usize] = ((*psSilk_VAD).NrgRatioSmth_Q8[b as usize] + as i64 + + ((NrgToNoiseRatio_Q8[b as usize] - (*psSilk_VAD).NrgRatioSmth_Q8[b as usize]) as i64 + * smooth_coef_Q16 as i16 as i64 + >> 16)) as i32; + SNR_Q7 = 3 * (silk_lin2log((*psSilk_VAD).NrgRatioSmth_Q8[b as usize]) - 8 * 128); + (*psEncC).input_quality_bands_Q15[b as usize] = silk_sigm_Q15(SNR_Q7 - 16 * 128 >> 4); + b += 1; + } + return ret; +} +#[inline] +unsafe fn silk_VAD_GetNoiseLevels(pX: *const i32, psSilk_VAD: *mut silk_VAD_state) { + let mut k: i32 = 0; + let mut nl: i32 = 0; + let mut nrg: i32 = 0; + let mut inv_nrg: i32 = 0; + let mut coef: i32 = 0; + let mut min_coef: i32 = 0; + if (*psSilk_VAD).counter < 1000 { + min_coef = 0x7fff / (((*psSilk_VAD).counter >> 4) + 1); + (*psSilk_VAD).counter += 1; + } else { + min_coef = 0; + } + k = 0; + while k < VAD_N_BANDS { + nl = (*psSilk_VAD).NL[k as usize]; + nrg = if (*pX.offset(k as isize) as u32) + .wrapping_add((*psSilk_VAD).NoiseLevelBias[k as usize] as u32) + & 0x80000000 as u32 + != 0 + { + silk_int32_MAX + } else { + *pX.offset(k as isize) + (*psSilk_VAD).NoiseLevelBias[k as usize] + }; + inv_nrg = 0x7fffffff / nrg; + if nrg > ((nl as u32) << 3) as i32 { + coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; + } else if nrg < nl { + coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; + } else { + coef = ((inv_nrg as i64 * nl as i64 >> 16) as i32 as i64 * ((1024) << 1) as i16 as i64 + >> 16) as i32; + } + coef = silk_max_int(coef, min_coef); + (*psSilk_VAD).inv_NL[k as usize] = ((*psSilk_VAD).inv_NL[k as usize] as i64 + + ((inv_nrg - (*psSilk_VAD).inv_NL[k as usize]) as i64 * coef as i16 as i64 >> 16)) + as i32; + nl = 0x7fffffff / (*psSilk_VAD).inv_NL[k as usize]; + nl = if nl < 0xffffff { nl } else { 0xffffff }; + (*psSilk_VAD).NL[k as usize] = nl; + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/VQ_WMat_EC.rs b/vendor/unsafe-libopus/src/silk/VQ_WMat_EC.rs new file mode 100644 index 00000000..a80d04d5 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/VQ_WMat_EC.rs @@ -0,0 +1,104 @@ +use crate::silk::lin2log::silk_lin2log; + +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; +} +pub use self::typedef_h::silk_int32_MAX; +use crate::silk::define::LTP_ORDER; + +pub unsafe fn silk_VQ_WMat_EC_c( + ind: *mut i8, + res_nrg_Q15: *mut i32, + rate_dist_Q8: *mut i32, + gain_Q7: *mut i32, + XX_Q17: *const i32, + xX_Q17: *const i32, + cb_Q7: *const i8, + cb_gain_Q7: *const u8, + cl_Q5: *const u8, + subfr_len: i32, + max_gain_Q7: i32, + L: i32, +) { + let mut k: i32 = 0; + let mut gain_tmp_Q7: i32 = 0; + let mut cb_row_Q7: *const i8 = 0 as *const i8; + let mut neg_xX_Q24: [i32; 5] = [0; 5]; + let mut sum1_Q15: i32 = 0; + let mut sum2_Q24: i32 = 0; + let mut bits_res_Q8: i32 = 0; + let mut bits_tot_Q8: i32 = 0; + neg_xX_Q24[0 as usize] = -(((*xX_Q17.offset(0 as isize) as u32) << 7) as i32); + neg_xX_Q24[1 as usize] = -(((*xX_Q17.offset(1 as isize) as u32) << 7) as i32); + neg_xX_Q24[2 as usize] = -(((*xX_Q17.offset(2 as isize) as u32) << 7) as i32); + neg_xX_Q24[3 as usize] = -(((*xX_Q17.offset(3 as isize) as u32) << 7) as i32); + neg_xX_Q24[4 as usize] = -(((*xX_Q17.offset(4 as isize) as u32) << 7) as i32); + *rate_dist_Q8 = silk_int32_MAX; + *res_nrg_Q15 = silk_int32_MAX; + cb_row_Q7 = cb_Q7; + *ind = 0; + k = 0; + while k < L { + let mut penalty: i32 = 0; + gain_tmp_Q7 = *cb_gain_Q7.offset(k as isize) as i32; + sum1_Q15 = (1.001f64 * ((1) << 15) as f64 + 0.5f64) as i32; + penalty = (((if gain_tmp_Q7 - max_gain_Q7 > 0 { + gain_tmp_Q7 - max_gain_Q7 + } else { + 0 + }) as u32) + << 11) as i32; + sum2_Q24 = neg_xX_Q24[0 as usize] + + *XX_Q17.offset(1 as isize) * *cb_row_Q7.offset(1 as isize) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(2 as isize) * *cb_row_Q7.offset(2 as isize) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(3 as isize) * *cb_row_Q7.offset(3 as isize) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(4 as isize) * *cb_row_Q7.offset(4 as isize) as i32; + sum2_Q24 = ((sum2_Q24 as u32) << 1) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(0 as isize) * *cb_row_Q7.offset(0 as isize) as i32; + sum1_Q15 = (sum1_Q15 as i64 + + (sum2_Q24 as i64 * *cb_row_Q7.offset(0 as isize) as i16 as i64 >> 16)) + as i32; + sum2_Q24 = neg_xX_Q24[1 as usize] + + *XX_Q17.offset(7 as isize) * *cb_row_Q7.offset(2 as isize) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(8 as isize) * *cb_row_Q7.offset(3 as isize) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(9 as isize) * *cb_row_Q7.offset(4 as isize) as i32; + sum2_Q24 = ((sum2_Q24 as u32) << 1) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(6 as isize) * *cb_row_Q7.offset(1 as isize) as i32; + sum1_Q15 = (sum1_Q15 as i64 + + (sum2_Q24 as i64 * *cb_row_Q7.offset(1 as isize) as i16 as i64 >> 16)) + as i32; + sum2_Q24 = neg_xX_Q24[2 as usize] + + *XX_Q17.offset(13 as isize) * *cb_row_Q7.offset(3 as isize) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(14 as isize) * *cb_row_Q7.offset(4 as isize) as i32; + sum2_Q24 = ((sum2_Q24 as u32) << 1) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(12 as isize) * *cb_row_Q7.offset(2 as isize) as i32; + sum1_Q15 = (sum1_Q15 as i64 + + (sum2_Q24 as i64 * *cb_row_Q7.offset(2 as isize) as i16 as i64 >> 16)) + as i32; + sum2_Q24 = neg_xX_Q24[3 as usize] + + *XX_Q17.offset(19 as isize) * *cb_row_Q7.offset(4 as isize) as i32; + sum2_Q24 = ((sum2_Q24 as u32) << 1) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(18 as isize) * *cb_row_Q7.offset(3 as isize) as i32; + sum1_Q15 = (sum1_Q15 as i64 + + (sum2_Q24 as i64 * *cb_row_Q7.offset(3 as isize) as i16 as i64 >> 16)) + as i32; + sum2_Q24 = ((neg_xX_Q24[4 as usize] as u32) << 1) as i32; + sum2_Q24 = sum2_Q24 + *XX_Q17.offset(24 as isize) * *cb_row_Q7.offset(4 as isize) as i32; + sum1_Q15 = (sum1_Q15 as i64 + + (sum2_Q24 as i64 * *cb_row_Q7.offset(4 as isize) as i16 as i64 >> 16)) + as i32; + if sum1_Q15 >= 0 { + bits_res_Q8 = subfr_len as i16 as i32 + * (silk_lin2log(sum1_Q15 + penalty) - ((15) << 7)) as i16 as i32; + bits_tot_Q8 = bits_res_Q8 + ((*cl_Q5.offset(k as isize) as u32) << 3 - 1) as i32; + if bits_tot_Q8 <= *rate_dist_Q8 { + *rate_dist_Q8 = bits_tot_Q8; + *res_nrg_Q15 = sum1_Q15 + penalty; + *ind = k as i8; + *gain_Q7 = gain_tmp_Q7; + } + } + cb_row_Q7 = cb_row_Q7.offset(LTP_ORDER as isize); + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/ana_filt_bank_1.rs b/vendor/unsafe-libopus/src/silk/ana_filt_bank_1.rs new file mode 100644 index 00000000..5d500bd5 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/ana_filt_bank_1.rs @@ -0,0 +1,76 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +static mut A_fb1_20: i16 = ((5394) << 1) as i16; +static mut A_fb1_21: i16 = -(24290) as i16; +pub unsafe fn silk_ana_filt_bank_1( + in_0: *const i16, + S: *mut i32, + outL: *mut i16, + outH: *mut i16, + N: i32, +) { + let mut k: i32 = 0; + let N2: i32 = N >> 1; + let mut in32: i32 = 0; + let mut X: i32 = 0; + let mut Y: i32 = 0; + let mut out_1: i32 = 0; + let mut out_2: i32 = 0; + k = 0; + while k < N2 { + in32 = ((*in_0.offset((2 * k) as isize) as i32 as u32) << 10) as i32; + Y = in32 - *S.offset(0 as isize); + X = (Y as i64 + (Y as i64 * A_fb1_21 as i64 >> 16)) as i32; + out_1 = *S.offset(0 as isize) + X; + *S.offset(0 as isize) = in32 + X; + in32 = ((*in_0.offset((2 * k + 1) as isize) as i32 as u32) << 10) as i32; + Y = in32 - *S.offset(1 as isize); + X = (Y as i64 * A_fb1_20 as i64 >> 16) as i32; + out_2 = *S.offset(1 as isize) + X; + *S.offset(1 as isize) = in32 + X; + *outL.offset(k as isize) = (if (if 11 == 1 { + (out_2 + out_1 >> 1) + (out_2 + out_1 & 1) + } else { + (out_2 + out_1 >> 11 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 11 == 1 { + (out_2 + out_1 >> 1) + (out_2 + out_1 & 1) + } else { + (out_2 + out_1 >> 11 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 11 == 1 { + (out_2 + out_1 >> 1) + (out_2 + out_1 & 1) + } else { + (out_2 + out_1 >> 11 - 1) + 1 >> 1 + }) as i16; + *outH.offset(k as isize) = (if (if 11 == 1 { + (out_2 - out_1 >> 1) + (out_2 - out_1 & 1) + } else { + (out_2 - out_1 >> 11 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 11 == 1 { + (out_2 - out_1 >> 1) + (out_2 - out_1 & 1) + } else { + (out_2 - out_1 >> 11 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 11 == 1 { + (out_2 - out_1 >> 1) + (out_2 - out_1 & 1) + } else { + (out_2 - out_1 >> 11 - 1) + 1 >> 1 + }) as i16; + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/biquad_alt.rs b/vendor/unsafe-libopus/src/silk/biquad_alt.rs new file mode 100644 index 00000000..f672149f --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/biquad_alt.rs @@ -0,0 +1,68 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +pub unsafe fn silk_biquad_alt_stride1( + in_0: *const i16, + B_Q28: *const i32, + A_Q28: *const i32, + S: *mut i32, + out: *mut i16, + len: i32, +) { + let mut k: i32 = 0; + let mut inval: i32 = 0; + let mut A0_U_Q28: i32 = 0; + let mut A0_L_Q28: i32 = 0; + let mut A1_U_Q28: i32 = 0; + let mut A1_L_Q28: i32 = 0; + let mut out32_Q14: i32 = 0; + A0_L_Q28 = -*A_Q28.offset(0 as isize) & 0x3fff; + A0_U_Q28 = -*A_Q28.offset(0 as isize) >> 14; + A1_L_Q28 = -*A_Q28.offset(1 as isize) & 0x3fff; + A1_U_Q28 = -*A_Q28.offset(1 as isize) >> 14; + k = 0; + while k < len { + inval = *in_0.offset(k as isize) as i32; + out32_Q14 = (((*S.offset(0 as isize) as i64 + + (*B_Q28.offset(0 as isize) as i64 * inval as i16 as i64 >> 16)) + as i32 as u32) + << 2) as i32; + *S.offset(0 as isize) = *S.offset(1 as isize) + + (if 14 == 1 { + ((out32_Q14 as i64 * A0_L_Q28 as i16 as i64 >> 16) as i32 >> 1) + + ((out32_Q14 as i64 * A0_L_Q28 as i16 as i64 >> 16) as i32 & 1) + } else { + ((out32_Q14 as i64 * A0_L_Q28 as i16 as i64 >> 16) as i32 >> 14 - 1) + 1 >> 1 + }); + *S.offset(0 as isize) = (*S.offset(0 as isize) as i64 + + (out32_Q14 as i64 * A0_U_Q28 as i16 as i64 >> 16)) + as i32; + *S.offset(0 as isize) = (*S.offset(0 as isize) as i64 + + (*B_Q28.offset(1 as isize) as i64 * inval as i16 as i64 >> 16)) + as i32; + *S.offset(1 as isize) = if 14 == 1 { + ((out32_Q14 as i64 * A1_L_Q28 as i16 as i64 >> 16) as i32 >> 1) + + ((out32_Q14 as i64 * A1_L_Q28 as i16 as i64 >> 16) as i32 & 1) + } else { + ((out32_Q14 as i64 * A1_L_Q28 as i16 as i64 >> 16) as i32 >> 14 - 1) + 1 >> 1 + }; + *S.offset(1 as isize) = (*S.offset(1 as isize) as i64 + + (out32_Q14 as i64 * A1_U_Q28 as i16 as i64 >> 16)) + as i32; + *S.offset(1 as isize) = (*S.offset(1 as isize) as i64 + + (*B_Q28.offset(2 as isize) as i64 * inval as i16 as i64 >> 16)) + as i32; + *out.offset(k as isize) = (if out32_Q14 + ((1) << 14) - 1 >> 14 > silk_int16_MAX { + silk_int16_MAX + } else if (out32_Q14 + ((1) << 14) - 1 >> 14) < silk_int16_MIN { + silk_int16_MIN + } else { + out32_Q14 + ((1) << 14) - 1 >> 14 + }) as i16; + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/bwexpander.rs b/vendor/unsafe-libopus/src/silk/bwexpander.rs new file mode 100644 index 00000000..8a36310e --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/bwexpander.rs @@ -0,0 +1,25 @@ +pub unsafe fn silk_bwexpander(ar: *mut i16, d: i32, mut chirp_Q16: i32) { + let mut i: i32 = 0; + let chirp_minus_one_Q16: i32 = chirp_Q16 - 65536; + i = 0; + while i < d - 1 { + *ar.offset(i as isize) = (if 16 == 1 { + (chirp_Q16 * *ar.offset(i as isize) as i32 >> 1) + + (chirp_Q16 * *ar.offset(i as isize) as i32 & 1) + } else { + (chirp_Q16 * *ar.offset(i as isize) as i32 >> 16 - 1) + 1 >> 1 + }) as i16; + chirp_Q16 += if 16 == 1 { + (chirp_Q16 * chirp_minus_one_Q16 >> 1) + (chirp_Q16 * chirp_minus_one_Q16 & 1) + } else { + (chirp_Q16 * chirp_minus_one_Q16 >> 16 - 1) + 1 >> 1 + }; + i += 1; + } + *ar.offset((d - 1) as isize) = (if 16 == 1 { + (chirp_Q16 * *ar.offset((d - 1) as isize) as i32 >> 1) + + (chirp_Q16 * *ar.offset((d - 1) as isize) as i32 & 1) + } else { + (chirp_Q16 * *ar.offset((d - 1) as isize) as i32 >> 16 - 1) + 1 >> 1 + }) as i16; +} diff --git a/vendor/unsafe-libopus/src/silk/bwexpander_32.rs b/vendor/unsafe-libopus/src/silk/bwexpander_32.rs new file mode 100644 index 00000000..331515ea --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/bwexpander_32.rs @@ -0,0 +1,16 @@ +pub unsafe fn silk_bwexpander_32(ar: *mut i32, d: i32, mut chirp_Q16: i32) { + let mut i: i32 = 0; + let chirp_minus_one_Q16: i32 = chirp_Q16 - 65536; + i = 0; + while i < d - 1 { + *ar.offset(i as isize) = (chirp_Q16 as i64 * *ar.offset(i as isize) as i64 >> 16) as i32; + chirp_Q16 += if 16 == 1 { + (chirp_Q16 * chirp_minus_one_Q16 >> 1) + (chirp_Q16 * chirp_minus_one_Q16 & 1) + } else { + (chirp_Q16 * chirp_minus_one_Q16 >> 16 - 1) + 1 >> 1 + }; + i += 1; + } + *ar.offset((d - 1) as isize) = + (chirp_Q16 as i64 * *ar.offset((d - 1) as isize) as i64 >> 16) as i32; +} diff --git a/vendor/unsafe-libopus/src/silk/check_control_input.rs b/vendor/unsafe-libopus/src/silk/check_control_input.rs new file mode 100644 index 00000000..f0b31447 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/check_control_input.rs @@ -0,0 +1,94 @@ +#[allow(unused)] +pub mod errors_h { + pub const SILK_NO_ERROR: i32 = 0; + pub const SILK_ENC_INVALID_COMPLEXITY_SETTING: i32 = -(106); + pub const SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR: i32 = -(111); + pub const SILK_ENC_INVALID_INBAND_FEC_SETTING: i32 = -(107); + pub const SILK_ENC_INVALID_CBR_SETTING: i32 = -(109); + pub const SILK_ENC_INVALID_DTX_SETTING: i32 = -(108); + pub const SILK_ENC_INVALID_LOSS_RATE: i32 = -(105); + pub const SILK_ENC_PACKET_SIZE_NOT_SUPPORTED: i32 = -(103); + pub const SILK_ENC_FS_NOT_SUPPORTED: i32 = -(102); +} + +pub use self::errors_h::{ + SILK_ENC_FS_NOT_SUPPORTED, SILK_ENC_INVALID_CBR_SETTING, SILK_ENC_INVALID_COMPLEXITY_SETTING, + SILK_ENC_INVALID_DTX_SETTING, SILK_ENC_INVALID_INBAND_FEC_SETTING, SILK_ENC_INVALID_LOSS_RATE, + SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR, SILK_ENC_PACKET_SIZE_NOT_SUPPORTED, SILK_NO_ERROR, +}; +use crate::silk::define::ENCODER_NUM_CHANNELS; +use crate::silk::enc_API::silk_EncControlStruct; + +pub unsafe fn check_control_input(encControl: *mut silk_EncControlStruct) -> i32 { + // The assert(0) here are weird.. + // they are optional (enabled only if ENABLE_ASSERTIONS is defined) + // if they are disabled - the function returns various error codes.. + // will figure something out later + + assert!(!encControl.is_null()); + if (*encControl).API_sampleRate != 8000 + && (*encControl).API_sampleRate != 12000 + && (*encControl).API_sampleRate != 16000 + && (*encControl).API_sampleRate != 24000 + && (*encControl).API_sampleRate != 32000 + && (*encControl).API_sampleRate != 44100 + && (*encControl).API_sampleRate != 48000 + || (*encControl).desiredInternalSampleRate != 8000 + && (*encControl).desiredInternalSampleRate != 12000 + && (*encControl).desiredInternalSampleRate != 16000 + || (*encControl).maxInternalSampleRate != 8000 + && (*encControl).maxInternalSampleRate != 12000 + && (*encControl).maxInternalSampleRate != 16000 + || (*encControl).minInternalSampleRate != 8000 + && (*encControl).minInternalSampleRate != 12000 + && (*encControl).minInternalSampleRate != 16000 + || (*encControl).minInternalSampleRate > (*encControl).desiredInternalSampleRate + || (*encControl).maxInternalSampleRate < (*encControl).desiredInternalSampleRate + || (*encControl).minInternalSampleRate > (*encControl).maxInternalSampleRate + { + panic!("libopus: assert(0) called"); + // return SILK_ENC_FS_NOT_SUPPORTED; + } + if (*encControl).payloadSize_ms != 10 + && (*encControl).payloadSize_ms != 20 + && (*encControl).payloadSize_ms != 40 + && (*encControl).payloadSize_ms != 60 + { + panic!("libopus: assert(0) called"); + // return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; + } + if (*encControl).packetLossPercentage < 0 || (*encControl).packetLossPercentage > 100 { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_LOSS_RATE; + } + if (*encControl).useDTX < 0 || (*encControl).useDTX > 1 { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_DTX_SETTING; + } + if (*encControl).useCBR < 0 || (*encControl).useCBR > 1 { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_CBR_SETTING; + } + if (*encControl).useInBandFEC < 0 || (*encControl).useInBandFEC > 1 { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_INBAND_FEC_SETTING; + } + if (*encControl).nChannelsAPI < 1 || (*encControl).nChannelsAPI > ENCODER_NUM_CHANNELS { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; + } + if (*encControl).nChannelsInternal < 1 || (*encControl).nChannelsInternal > ENCODER_NUM_CHANNELS + { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; + } + if (*encControl).nChannelsInternal > (*encControl).nChannelsAPI { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; + } + if (*encControl).complexity < 0 || (*encControl).complexity > 10 { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INVALID_COMPLEXITY_SETTING; + } + return SILK_NO_ERROR; +} diff --git a/vendor/unsafe-libopus/src/silk/code_signs.rs b/vendor/unsafe-libopus/src/silk/code_signs.rs new file mode 100644 index 00000000..b49f15df --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/code_signs.rs @@ -0,0 +1,75 @@ +use crate::celt::entdec::{ec_dec, ec_dec_icdf}; +use crate::celt::entenc::{ec_enc, ec_enc_icdf}; +use crate::silk::define::SHELL_CODEC_FRAME_LENGTH; +use crate::silk::tables_pulses_per_block::silk_sign_iCDF; + +pub fn silk_encode_signs( + psRangeEnc: &mut ec_enc, + pulses: &[i8], + length: i32, + signalType: i32, + quantOffsetType: i32, + sum_pulses: &[i32], +) { + let mut icdf: [u8; 2] = [0; 2]; + icdf[1] = 0; + let mut q_ptr = pulses; + + let i = 7 * (quantOffsetType + ((signalType as u32) << 1) as i32) as i16 as i32; + let icdf_ptr = &silk_sign_iCDF[i as usize..]; + + let length = (length + 16 / 2) >> 4; + for i in 0..length { + let p = sum_pulses[i as usize]; + if p > 0 { + icdf[0] = icdf_ptr[(p & 0x1f).min(6) as usize]; + + for j in 0..SHELL_CODEC_FRAME_LENGTH { + if q_ptr[j as usize] as i32 != 0 { + ec_enc_icdf(psRangeEnc, (q_ptr[j as usize] as i32 >> 15) + 1, &icdf, 8); + } + } + } + q_ptr = &q_ptr[SHELL_CODEC_FRAME_LENGTH as usize..]; + } +} +pub unsafe fn silk_decode_signs( + psRangeDec: &mut ec_dec, + pulses: *mut i16, + mut length: i32, + signalType: i32, + quantOffsetType: i32, + sum_pulses: *const i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut p: i32 = 0; + let mut icdf: [u8; 2] = [0; 2]; + let mut q_ptr: *mut i16 = 0 as *mut i16; + let mut icdf_ptr: *const u8 = 0 as *const u8; + icdf[1 as usize] = 0; + q_ptr = pulses; + i = 7 * (quantOffsetType + ((signalType as u32) << 1) as i32) as i16 as i32; + icdf_ptr = &*silk_sign_iCDF.as_ptr().offset(i as isize) as *const u8; + length = length + 16 / 2 >> 4; + i = 0; + while i < length { + p = *sum_pulses.offset(i as isize); + if p > 0 { + icdf[0 as usize] = + *icdf_ptr.offset((if (p & 0x1f) < 6 { p & 0x1f } else { 6 }) as isize); + j = 0; + while j < SHELL_CODEC_FRAME_LENGTH { + if *q_ptr.offset(j as isize) as i32 > 0 { + let ref mut fresh0 = *q_ptr.offset(j as isize); + *fresh0 = (*fresh0 as i32 + * (((ec_dec_icdf(psRangeDec, &icdf, 8) as u32) << 1) as i32 - 1)) + as i16; + } + j += 1; + } + } + q_ptr = q_ptr.offset(SHELL_CODEC_FRAME_LENGTH as isize); + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/control_SNR.rs b/vendor/unsafe-libopus/src/silk/control_SNR.rs new file mode 100644 index 00000000..64abad01 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/control_SNR.rs @@ -0,0 +1,67 @@ +pub mod errors_h { + pub const SILK_NO_ERROR: i32 = 0; +} +pub use self::errors_h::SILK_NO_ERROR; +use crate::silk::structs::silk_encoder_state; + +static mut silk_TargetRate_NB_21: [u8; 107] = [ + 0, 15, 39, 52, 61, 68, 74, 79, 84, 88, 92, 95, 99, 102, 105, 108, 111, 114, 117, 119, 122, 124, + 126, 129, 131, 133, 135, 137, 139, 142, 143, 145, 147, 149, 151, 153, 155, 157, 158, 160, 162, + 163, 165, 167, 168, 170, 171, 173, 174, 176, 177, 179, 180, 182, 183, 185, 186, 187, 189, 190, + 192, 193, 194, 196, 197, 199, 200, 201, 203, 204, 205, 207, 208, 209, 211, 212, 213, 215, 216, + 217, 219, 220, 221, 223, 224, 225, 227, 228, 230, 231, 232, 234, 235, 236, 238, 239, 241, 242, + 243, 245, 246, 248, 249, 250, 252, 253, 255, +]; +static mut silk_TargetRate_MB_21: [u8; 155] = [ + 0, 0, 28, 43, 52, 59, 65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98, 100, 102, 105, 107, 109, 111, + 113, 115, 116, 118, 120, 122, 123, 125, 127, 128, 130, 131, 133, 134, 136, 137, 138, 140, 141, + 143, 144, 145, 147, 148, 149, 151, 152, 153, 154, 156, 157, 158, 159, 160, 162, 163, 164, 165, + 166, 167, 168, 169, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, +]; +static mut silk_TargetRate_WB_21: [u8; 191] = [ + 0, 0, 0, 8, 29, 41, 49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99, 101, 103, + 105, 107, 108, 110, 112, 113, 115, 116, 118, 119, 121, 122, 123, 125, 126, 127, 129, 130, 131, + 132, 134, 135, 136, 137, 138, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 171, 172, 173, 174, 175, 176, 177, 177, 178, 179, 180, 181, 181, 182, 183, 184, 185, 185, 186, + 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, 195, 195, 196, 197, 198, 198, 199, 200, 200, + 201, 202, 203, 203, 204, 205, 206, 206, 207, 208, 209, 209, 210, 211, 211, 212, 213, 214, 214, + 215, 216, 216, 217, 218, 219, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 226, 227, 228, + 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, + 243, 243, 244, 245, 246, 246, 247, 248, 249, 249, 250, 251, 252, 253, 255, +]; +pub unsafe fn silk_control_SNR(psEncC: *mut silk_encoder_state, mut TargetRate_bps: i32) -> i32 { + let mut id: i32 = 0; + let mut bound: i32 = 0; + let mut snr_table: *const u8 = 0 as *const u8; + (*psEncC).TargetRate_bps = TargetRate_bps; + if (*psEncC).nb_subfr == 2 { + TargetRate_bps -= 2000 + (*psEncC).fs_kHz / 16; + } + if (*psEncC).fs_kHz == 8 { + bound = ::core::mem::size_of::<[u8; 107]>() as u64 as i32; + snr_table = silk_TargetRate_NB_21.as_ptr(); + } else if (*psEncC).fs_kHz == 12 { + bound = ::core::mem::size_of::<[u8; 155]>() as u64 as i32; + snr_table = silk_TargetRate_MB_21.as_ptr(); + } else { + bound = ::core::mem::size_of::<[u8; 191]>() as u64 as i32; + snr_table = silk_TargetRate_WB_21.as_ptr(); + } + id = (TargetRate_bps + 200) / 400; + id = if (id - 10) < bound - 1 { + id - 10 + } else { + bound - 1 + }; + if id <= 0 { + (*psEncC).SNR_dB_Q7 = 0; + } else { + (*psEncC).SNR_dB_Q7 = *snr_table.offset(id as isize) as i32 * 21; + } + return SILK_NO_ERROR; +} diff --git a/vendor/unsafe-libopus/src/silk/control_audio_bandwidth.rs b/vendor/unsafe-libopus/src/silk/control_audio_bandwidth.rs new file mode 100644 index 00000000..10dfd9e7 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/control_audio_bandwidth.rs @@ -0,0 +1,88 @@ +use crate::externs::memset; +use crate::silk::define::TRANSITION_FRAMES; +use crate::silk::enc_API::silk_EncControlStruct; +use crate::silk::structs::silk_encoder_state; +pub unsafe fn silk_control_audio_bandwidth( + psEncC: *mut silk_encoder_state, + encControl: *mut silk_EncControlStruct, +) -> i32 { + let mut fs_kHz: i32 = 0; + let mut orig_kHz: i32 = 0; + let mut fs_Hz: i32 = 0; + orig_kHz = (*psEncC).fs_kHz; + if orig_kHz == 0 { + orig_kHz = (*psEncC).sLP.saved_fs_kHz; + } + fs_kHz = orig_kHz; + fs_Hz = fs_kHz as i16 as i32 * 1000; + if fs_Hz == 0 { + fs_Hz = if (*psEncC).desiredInternal_fs_Hz < (*psEncC).API_fs_Hz { + (*psEncC).desiredInternal_fs_Hz + } else { + (*psEncC).API_fs_Hz + }; + fs_kHz = fs_Hz / 1000; + } else if fs_Hz > (*psEncC).API_fs_Hz + || fs_Hz > (*psEncC).maxInternal_fs_Hz + || fs_Hz < (*psEncC).minInternal_fs_Hz + { + fs_Hz = (*psEncC).API_fs_Hz; + fs_Hz = if fs_Hz < (*psEncC).maxInternal_fs_Hz { + fs_Hz + } else { + (*psEncC).maxInternal_fs_Hz + }; + fs_Hz = if fs_Hz > (*psEncC).minInternal_fs_Hz { + fs_Hz + } else { + (*psEncC).minInternal_fs_Hz + }; + fs_kHz = fs_Hz / 1000; + } else { + if (*psEncC).sLP.transition_frame_no >= TRANSITION_FRAMES { + (*psEncC).sLP.mode = 0; + } + if (*psEncC).allow_bandwidth_switch != 0 || (*encControl).opusCanSwitch != 0 { + if orig_kHz as i16 as i32 * 1000 > (*psEncC).desiredInternal_fs_Hz { + if (*psEncC).sLP.mode == 0 { + (*psEncC).sLP.transition_frame_no = TRANSITION_FRAMES; + memset( + ((*psEncC).sLP.In_LP_State).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 2]>() as u64, + ); + } + if (*encControl).opusCanSwitch != 0 { + (*psEncC).sLP.mode = 0; + fs_kHz = if orig_kHz == 16 { 12 } else { 8 }; + } else if (*psEncC).sLP.transition_frame_no <= 0 { + (*encControl).switchReady = 1; + (*encControl).maxBits -= + (*encControl).maxBits * 5 / ((*encControl).payloadSize_ms + 5); + } else { + (*psEncC).sLP.mode = -(2); + } + } else if (orig_kHz as i16 as i32 * 1000) < (*psEncC).desiredInternal_fs_Hz { + if (*encControl).opusCanSwitch != 0 { + fs_kHz = if orig_kHz == 8 { 12 } else { 16 }; + (*psEncC).sLP.transition_frame_no = 0; + memset( + ((*psEncC).sLP.In_LP_State).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 2]>() as u64, + ); + (*psEncC).sLP.mode = 1; + } else if (*psEncC).sLP.mode == 0 { + (*encControl).switchReady = 1; + (*encControl).maxBits -= + (*encControl).maxBits * 5 / ((*encControl).payloadSize_ms + 5); + } else { + (*psEncC).sLP.mode = 1; + } + } else if (*psEncC).sLP.mode < 0 { + (*psEncC).sLP.mode = 1; + } + } + } + return fs_kHz; +} diff --git a/vendor/unsafe-libopus/src/silk/control_codec.rs b/vendor/unsafe-libopus/src/silk/control_codec.rs new file mode 100644 index 00000000..ee9a82e9 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/control_codec.rs @@ -0,0 +1,390 @@ +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub mod errors_h { + pub const SILK_ENC_PACKET_SIZE_NOT_SUPPORTED: i32 = -(103); + pub const SILK_NO_ERROR: i32 = 0; +} +pub mod SigProc_FLP_h { + #[inline] + pub unsafe fn silk_float2short_array(out: *mut i16, in_0: *const f32, length: i32) { + let mut k: i32 = 0; + k = length - 1; + while k >= 0 { + *out.offset(k as isize) = (if float2int(*in_0.offset(k as isize)) > silk_int16_MAX { + silk_int16_MAX + } else if float2int(*in_0.offset(k as isize)) < silk_int16_MIN { + silk_int16_MIN + } else { + float2int(*in_0.offset(k as isize)) + }) as i16; + k -= 1; + } + } + #[inline] + pub unsafe fn silk_short2float_array(out: *mut f32, in_0: *const i16, length: i32) { + let mut k: i32 = 0; + k = length - 1; + while k >= 0 { + *out.offset(k as isize) = *in_0.offset(k as isize) as f32; + k -= 1; + } + } + use super::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + use crate::celt::float_cast::float2int; +} +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +use self::errors_h::{SILK_ENC_PACKET_SIZE_NOT_SUPPORTED, SILK_NO_ERROR}; +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +pub use self::SigProc_FLP_h::{silk_float2short_array, silk_short2float_array}; +use crate::externs::memset; +use crate::silk::control_audio_bandwidth::silk_control_audio_bandwidth; +use crate::silk::define::{ + LA_SHAPE_MS, MAX_DEL_DEC_STATES, MAX_LPC_ORDER, MAX_NB_SUBFR, MIN_LPC_ORDER, + SUB_FRAME_LENGTH_MS, TYPE_NO_VOICE_ACTIVITY, +}; +use crate::silk::enc_API::silk_EncControlStruct; +use crate::silk::float::structs_FLP::{silk_encoder_state_FLP, silk_shape_state_FLP}; +use crate::silk::pitch_est_tables::{ + SILK_PE_MAX_COMPLEX, SILK_PE_MID_COMPLEX, SILK_PE_MIN_COMPLEX, +}; +use crate::silk::resampler::{silk_resampler, silk_resampler_init}; +use crate::silk::structs::{silk_encoder_state, silk_nsq_state}; +use crate::silk::tables_NLSF_CB_NB_MB::silk_NLSF_CB_NB_MB; +use crate::silk::tables_NLSF_CB_WB::silk_NLSF_CB_WB; +use crate::silk::tables_other::{silk_uniform4_iCDF, silk_uniform6_iCDF, silk_uniform8_iCDF}; +use crate::silk::tables_pitch_lag::{ + silk_pitch_contour_10_ms_NB_iCDF, silk_pitch_contour_10_ms_iCDF, silk_pitch_contour_NB_iCDF, + silk_pitch_contour_iCDF, +}; +use crate::silk::SigProc_FIX::{silk_max_int, silk_min_int}; + +pub unsafe fn silk_control_encoder( + psEnc: *mut silk_encoder_state_FLP, + encControl: *mut silk_EncControlStruct, + allow_bw_switch: i32, + channelNb: i32, + force_fs_kHz: i32, +) -> i32 { + let mut fs_kHz: i32 = 0; + let mut ret: i32 = 0; + (*psEnc).sCmn.useDTX = (*encControl).useDTX; + (*psEnc).sCmn.useCBR = (*encControl).useCBR; + (*psEnc).sCmn.API_fs_Hz = (*encControl).API_sampleRate; + (*psEnc).sCmn.maxInternal_fs_Hz = (*encControl).maxInternalSampleRate; + (*psEnc).sCmn.minInternal_fs_Hz = (*encControl).minInternalSampleRate; + (*psEnc).sCmn.desiredInternal_fs_Hz = (*encControl).desiredInternalSampleRate; + (*psEnc).sCmn.useInBandFEC = (*encControl).useInBandFEC; + (*psEnc).sCmn.nChannelsAPI = (*encControl).nChannelsAPI; + (*psEnc).sCmn.nChannelsInternal = (*encControl).nChannelsInternal; + (*psEnc).sCmn.allow_bandwidth_switch = allow_bw_switch; + (*psEnc).sCmn.channelNb = channelNb; + if (*psEnc).sCmn.controlled_since_last_payload != 0 && (*psEnc).sCmn.prefillFlag == 0 { + if (*psEnc).sCmn.API_fs_Hz != (*psEnc).sCmn.prev_API_fs_Hz && (*psEnc).sCmn.fs_kHz > 0 { + ret += silk_setup_resamplers(psEnc, (*psEnc).sCmn.fs_kHz); + } + return ret; + } + fs_kHz = silk_control_audio_bandwidth(&mut (*psEnc).sCmn, encControl); + if force_fs_kHz != 0 { + fs_kHz = force_fs_kHz; + } + ret += silk_setup_resamplers(psEnc, fs_kHz); + ret += silk_setup_fs(psEnc, fs_kHz, (*encControl).payloadSize_ms); + ret += silk_setup_complexity(&mut (*psEnc).sCmn, (*encControl).complexity); + (*psEnc).sCmn.PacketLoss_perc = (*encControl).packetLossPercentage; + ret += silk_setup_LBRR(&mut (*psEnc).sCmn, encControl); + (*psEnc).sCmn.controlled_since_last_payload = 1; + return ret; +} +unsafe fn silk_setup_resamplers(psEnc: *mut silk_encoder_state_FLP, fs_kHz: i32) -> i32 { + let mut ret: i32 = SILK_NO_ERROR; + if (*psEnc).sCmn.fs_kHz != fs_kHz || (*psEnc).sCmn.prev_API_fs_Hz != (*psEnc).sCmn.API_fs_Hz { + if (*psEnc).sCmn.fs_kHz == 0 { + (*psEnc).sCmn.resampler_state = + silk_resampler_init((*psEnc).sCmn.API_fs_Hz, fs_kHz * 1000, 1); + } else { + let mut new_buf_samples: i32 = 0; + let mut api_buf_samples: i32 = 0; + let mut old_buf_samples: i32 = 0; + let mut buf_length_ms: i32 = 0; + buf_length_ms = ((((*psEnc).sCmn.nb_subfr * 5) as u32) << 1) as i32 + LA_SHAPE_MS; + old_buf_samples = buf_length_ms * (*psEnc).sCmn.fs_kHz; + new_buf_samples = buf_length_ms * fs_kHz; + let vla = (if old_buf_samples > new_buf_samples { + old_buf_samples + } else { + new_buf_samples + }) as usize; + let mut x_bufFIX: Vec = ::std::vec::from_elem(0, vla); + silk_float2short_array( + x_bufFIX.as_mut_ptr(), + ((*psEnc).x_buf).as_mut_ptr(), + old_buf_samples, + ); + + /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ + let mut temp_resampler_state = silk_resampler_init( + (*psEnc).sCmn.fs_kHz as i16 as i32 * 1000, + (*psEnc).sCmn.API_fs_Hz, + 0, + ); + + /* Calculate number of samples to temporarily upsample */ + api_buf_samples = buf_length_ms * ((*psEnc).sCmn.API_fs_Hz / 1000); + + /* Temporary resampling of x_buf data to API_fs_Hz */ + let vla_0 = api_buf_samples as usize; + let mut x_buf_API_fs_Hz: Vec = ::std::vec::from_elem(0, vla_0); + ret += silk_resampler( + &mut temp_resampler_state, + &mut x_buf_API_fs_Hz, + &x_bufFIX[..old_buf_samples as usize], + ); + (*psEnc).sCmn.resampler_state = + silk_resampler_init((*psEnc).sCmn.API_fs_Hz, fs_kHz as i16 as i32 * 1000, 1); + ret += silk_resampler( + &mut (*psEnc).sCmn.resampler_state, + &mut x_bufFIX, + &x_buf_API_fs_Hz[..api_buf_samples as usize], + ); + silk_short2float_array( + ((*psEnc).x_buf).as_mut_ptr(), + x_bufFIX.as_mut_ptr(), + new_buf_samples, + ); + } + } + (*psEnc).sCmn.prev_API_fs_Hz = (*psEnc).sCmn.API_fs_Hz; + return ret; +} +unsafe fn silk_setup_fs( + psEnc: *mut silk_encoder_state_FLP, + fs_kHz: i32, + PacketSize_ms: i32, +) -> i32 { + let mut ret: i32 = SILK_NO_ERROR; + if PacketSize_ms != (*psEnc).sCmn.PacketSize_ms { + if PacketSize_ms != 10 && PacketSize_ms != 20 && PacketSize_ms != 40 && PacketSize_ms != 60 + { + ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; + } + if PacketSize_ms <= 10 { + (*psEnc).sCmn.nFramesPerPacket = 1; + (*psEnc).sCmn.nb_subfr = if PacketSize_ms == 10 { 2 } else { 1 }; + (*psEnc).sCmn.frame_length = PacketSize_ms as i16 as i32 * fs_kHz as i16 as i32; + (*psEnc).sCmn.pitch_LPC_win_length = + (10 + ((2) << 1)) as i16 as i32 * fs_kHz as i16 as i32; + if (*psEnc).sCmn.fs_kHz == 8 { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_10_ms_NB_iCDF; + } else { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_10_ms_iCDF; + } + } else { + (*psEnc).sCmn.nFramesPerPacket = PacketSize_ms / (5 * 4); + (*psEnc).sCmn.nb_subfr = MAX_NB_SUBFR; + (*psEnc).sCmn.frame_length = 20 * fs_kHz as i16 as i32; + (*psEnc).sCmn.pitch_LPC_win_length = + (20 + ((2) << 1)) as i16 as i32 * fs_kHz as i16 as i32; + if (*psEnc).sCmn.fs_kHz == 8 { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_NB_iCDF; + } else { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_iCDF; + } + } + (*psEnc).sCmn.PacketSize_ms = PacketSize_ms; + (*psEnc).sCmn.TargetRate_bps = 0; + } + assert!(fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16); + assert!((*psEnc).sCmn.nb_subfr == 2 || (*psEnc).sCmn.nb_subfr == 4); + if (*psEnc).sCmn.fs_kHz != fs_kHz { + memset( + &mut (*psEnc).sShape as *mut silk_shape_state_FLP as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + memset( + &mut (*psEnc).sCmn.sNSQ as *mut silk_nsq_state as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + memset( + ((*psEnc).sCmn.prev_NLSFq_Q15).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 16]>() as u64, + ); + memset( + &mut (*psEnc).sCmn.sLP.In_LP_State as *mut [i32; 2] as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 2]>() as u64, + ); + (*psEnc).sCmn.inputBufIx = 0; + (*psEnc).sCmn.nFramesEncoded = 0; + (*psEnc).sCmn.TargetRate_bps = 0; + (*psEnc).sCmn.prevLag = 100; + (*psEnc).sCmn.first_frame_after_reset = 1; + (*psEnc).sShape.LastGainIndex = 10; + (*psEnc).sCmn.sNSQ.lagPrev = 100; + (*psEnc).sCmn.sNSQ.prev_gain_Q16 = 65536; + (*psEnc).sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY as i8; + (*psEnc).sCmn.fs_kHz = fs_kHz; + if (*psEnc).sCmn.fs_kHz == 8 { + if (*psEnc).sCmn.nb_subfr == MAX_NB_SUBFR { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_NB_iCDF; + } else { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_10_ms_NB_iCDF; + } + } else if (*psEnc).sCmn.nb_subfr == MAX_NB_SUBFR { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_iCDF; + } else { + (*psEnc).sCmn.pitch_contour_iCDF = &silk_pitch_contour_10_ms_iCDF; + } + if (*psEnc).sCmn.fs_kHz == 8 || (*psEnc).sCmn.fs_kHz == 12 { + (*psEnc).sCmn.predictLPCOrder = MIN_LPC_ORDER; + (*psEnc).sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB; + } else { + (*psEnc).sCmn.predictLPCOrder = MAX_LPC_ORDER; + (*psEnc).sCmn.psNLSF_CB = &silk_NLSF_CB_WB; + } + (*psEnc).sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz; + (*psEnc).sCmn.frame_length = + (*psEnc).sCmn.subfr_length as i16 as i32 * (*psEnc).sCmn.nb_subfr as i16 as i32; + (*psEnc).sCmn.ltp_mem_length = 20 * fs_kHz as i16 as i32; + (*psEnc).sCmn.la_pitch = 2 * fs_kHz as i16 as i32; + (*psEnc).sCmn.max_pitch_lag = 18 * fs_kHz as i16 as i32; + if (*psEnc).sCmn.nb_subfr == MAX_NB_SUBFR { + (*psEnc).sCmn.pitch_LPC_win_length = + (20 + ((2) << 1)) as i16 as i32 * fs_kHz as i16 as i32; + } else { + (*psEnc).sCmn.pitch_LPC_win_length = + (10 + ((2) << 1)) as i16 as i32 * fs_kHz as i16 as i32; + } + if (*psEnc).sCmn.fs_kHz == 16 { + (*psEnc).sCmn.pitch_lag_low_bits_iCDF = &silk_uniform8_iCDF; + } else if (*psEnc).sCmn.fs_kHz == 12 { + (*psEnc).sCmn.pitch_lag_low_bits_iCDF = &silk_uniform6_iCDF; + } else { + (*psEnc).sCmn.pitch_lag_low_bits_iCDF = &silk_uniform4_iCDF; + } + } + assert!((*psEnc).sCmn.subfr_length * (*psEnc).sCmn.nb_subfr == (*psEnc).sCmn.frame_length); + return ret; +} +unsafe fn silk_setup_complexity(psEncC: *mut silk_encoder_state, Complexity: i32) -> i32 { + let ret: i32 = 0; + assert!(Complexity >= 0 && Complexity <= 10); + if Complexity < 1 { + (*psEncC).pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.8f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 6; + (*psEncC).shapingLPCOrder = 12; + (*psEncC).la_shape = 3 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = 1; + (*psEncC).useInterpolatedNLSFs = 0; + (*psEncC).NLSF_MSVQ_Survivors = 2; + (*psEncC).warping_Q16 = 0; + } else if Complexity < 2 { + (*psEncC).pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.76f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 8; + (*psEncC).shapingLPCOrder = 14; + (*psEncC).la_shape = 5 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = 1; + (*psEncC).useInterpolatedNLSFs = 0; + (*psEncC).NLSF_MSVQ_Survivors = 3; + (*psEncC).warping_Q16 = 0; + } else if Complexity < 3 { + (*psEncC).pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.8f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 6; + (*psEncC).shapingLPCOrder = 12; + (*psEncC).la_shape = 3 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = 2; + (*psEncC).useInterpolatedNLSFs = 0; + (*psEncC).NLSF_MSVQ_Survivors = 2; + (*psEncC).warping_Q16 = 0; + } else if Complexity < 4 { + (*psEncC).pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.76f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 8; + (*psEncC).shapingLPCOrder = 14; + (*psEncC).la_shape = 5 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = 2; + (*psEncC).useInterpolatedNLSFs = 0; + (*psEncC).NLSF_MSVQ_Survivors = 4; + (*psEncC).warping_Q16 = 0; + } else if Complexity < 6 { + (*psEncC).pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.74f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 10; + (*psEncC).shapingLPCOrder = 16; + (*psEncC).la_shape = 5 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = 2; + (*psEncC).useInterpolatedNLSFs = 1; + (*psEncC).NLSF_MSVQ_Survivors = 6; + (*psEncC).warping_Q16 = + (*psEncC).fs_kHz * ((0.015f32 * ((1) << 16) as f32) as f64 + 0.5f64) as i32; + } else if Complexity < 8 { + (*psEncC).pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.72f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 12; + (*psEncC).shapingLPCOrder = 20; + (*psEncC).la_shape = 5 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = 3; + (*psEncC).useInterpolatedNLSFs = 1; + (*psEncC).NLSF_MSVQ_Survivors = 8; + (*psEncC).warping_Q16 = + (*psEncC).fs_kHz * ((0.015f32 * ((1) << 16) as f32) as f64 + 0.5f64) as i32; + } else { + (*psEncC).pitchEstimationComplexity = SILK_PE_MAX_COMPLEX; + (*psEncC).pitchEstimationThreshold_Q16 = (0.7f64 * ((1) << 16) as f64 + 0.5f64) as i32; + (*psEncC).pitchEstimationLPCOrder = 16; + (*psEncC).shapingLPCOrder = 24; + (*psEncC).la_shape = 5 * (*psEncC).fs_kHz; + (*psEncC).nStatesDelayedDecision = MAX_DEL_DEC_STATES; + (*psEncC).useInterpolatedNLSFs = 1; + (*psEncC).NLSF_MSVQ_Survivors = 16; + (*psEncC).warping_Q16 = + (*psEncC).fs_kHz * ((0.015f32 * ((1) << 16) as f32) as f64 + 0.5f64) as i32; + } + (*psEncC).pitchEstimationLPCOrder = + silk_min_int((*psEncC).pitchEstimationLPCOrder, (*psEncC).predictLPCOrder); + (*psEncC).shapeWinLength = SUB_FRAME_LENGTH_MS * (*psEncC).fs_kHz + 2 * (*psEncC).la_shape; + (*psEncC).Complexity = Complexity; + assert!((*psEncC).pitchEstimationLPCOrder <= 16); + assert!((*psEncC).shapingLPCOrder <= 24); + assert!((*psEncC).nStatesDelayedDecision <= 4); + assert!((*psEncC).warping_Q16 <= 32767); + assert!((*psEncC).la_shape <= 5 * 16); + assert!((*psEncC).shapeWinLength <= 15 * 16); + return ret; +} +#[inline] +unsafe fn silk_setup_LBRR( + psEncC: *mut silk_encoder_state, + encControl: *const silk_EncControlStruct, +) -> i32 { + let mut LBRR_in_previous_packet: i32 = 0; + let ret: i32 = SILK_NO_ERROR; + LBRR_in_previous_packet = (*psEncC).LBRR_enabled; + (*psEncC).LBRR_enabled = (*encControl).LBRR_coded; + if (*psEncC).LBRR_enabled != 0 { + if LBRR_in_previous_packet == 0 { + (*psEncC).LBRR_GainIncreases = 7; + } else { + (*psEncC).LBRR_GainIncreases = silk_max_int( + 7 - ((*psEncC).PacketLoss_perc as i64 + * (0.4f64 * ((1) << 16) as f64 + 0.5f64) as i32 as i16 as i64 + >> 16) as i32, + 2, + ); + } + } + return ret; +} diff --git a/vendor/unsafe-libopus/src/silk/debug.rs b/vendor/unsafe-libopus/src/silk/debug.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/debug.rs @@ -0,0 +1 @@ + diff --git a/vendor/unsafe-libopus/src/silk/dec_API.rs b/vendor/unsafe-libopus/src/silk/dec_API.rs new file mode 100644 index 00000000..cc6a14df --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/dec_API.rs @@ -0,0 +1,512 @@ +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_DecControlStruct { + pub nChannelsAPI: i32, + pub nChannelsInternal: i32, + pub API_sampleRate: i32, + pub internalSampleRate: i32, + pub payloadSize_ms: i32, + pub prevPitchLag: i32, +} +pub const FLAG_DECODE_NORMAL: i32 = 0; +pub const FLAG_DECODE_LBRR: i32 = 2; +pub const FLAG_PACKET_LOST: i32 = 1; +pub mod errors_h { + pub const SILK_DEC_INVALID_SAMPLING_FREQUENCY: i32 = -(200); + pub const SILK_NO_ERROR: i32 = 0; + #[allow(unused)] + pub const SILK_DEC_INVALID_FRAME_SIZE: i32 = -(203); +} +use self::errors_h::{SILK_DEC_INVALID_SAMPLING_FREQUENCY, SILK_NO_ERROR}; +use crate::celt::entdec::{ec_dec, ec_dec_bit_logp, ec_dec_icdf}; +use crate::externs::{memcpy, memset}; +use crate::silk::decode_frame::silk_decode_frame; +use crate::silk::decode_indices::silk_decode_indices; +use crate::silk::decode_pulses::silk_decode_pulses; +use crate::silk::decoder_set_fs::silk_decoder_set_fs; +use crate::silk::define::{ + CODE_CONDITIONALLY, CODE_INDEPENDENTLY, CODE_INDEPENDENTLY_NO_LTP_SCALING, + DECODER_NUM_CHANNELS, MAX_API_FS_KHZ, TYPE_NO_VOICE_ACTIVITY, TYPE_VOICED, +}; +use crate::silk::init_decoder::silk_init_decoder; +use crate::silk::resampler::silk_resampler; +use crate::silk::resampler::ResamplerState; +use crate::silk::stereo_MS_to_LR::silk_stereo_MS_to_LR; +use crate::silk::stereo_decode_pred::{silk_stereo_decode_mid_only, silk_stereo_decode_pred}; +use crate::silk::structs::{silk_decoder_state, stereo_dec_state}; +use crate::silk::tables_other::silk_LBRR_flags_iCDF_ptr; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_decoder { + pub channel_state: [silk_decoder_state; 2], + pub sStereo: stereo_dec_state, + pub nChannelsAPI: i32, + pub nChannelsInternal: i32, + pub prev_decode_only_middle: i32, +} +pub unsafe fn silk_Get_Decoder_Size(decSizeBytes: *mut i32) -> i32 { + let ret: i32 = SILK_NO_ERROR; + *decSizeBytes = ::core::mem::size_of::() as u64 as i32; + return ret; +} +pub unsafe fn silk_InitDecoder(decState: *mut core::ffi::c_void) -> i32 { + let mut n: i32 = 0; + let mut ret: i32 = SILK_NO_ERROR; + let channel_state: *mut silk_decoder_state = + ((*(decState as *mut silk_decoder)).channel_state).as_mut_ptr(); + n = 0; + while n < DECODER_NUM_CHANNELS { + ret = silk_init_decoder(&mut *channel_state.offset(n as isize)); + n += 1; + } + memset( + &mut (*(decState as *mut silk_decoder)).sStereo as *mut stereo_dec_state + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + (*(decState as *mut silk_decoder)).prev_decode_only_middle = 0; + return ret; +} +pub unsafe fn silk_Decode( + decState: *mut core::ffi::c_void, + decControl: *mut silk_DecControlStruct, + lostFlag: i32, + newPacketFlag: i32, + psRangeDec: &mut ec_dec, + samplesOut: *mut i16, + nSamplesOut: *mut i32, + arch: i32, +) -> i32 { + let mut i: i32 = 0; + let mut n: i32 = 0; + let mut decode_only_middle: i32 = 0; + let mut ret: i32 = SILK_NO_ERROR; + let mut nSamplesOutDec: i32 = 0; + let mut LBRR_symbol: i32 = 0; + let mut samplesOut1_tmp: [*mut i16; 2] = [0 as *mut i16; 2]; + let mut MS_pred_Q13: [i32; 2] = [0, 0]; + let psDec: *mut silk_decoder = decState as *mut silk_decoder; + let channel_state: *mut silk_decoder_state = ((*psDec).channel_state).as_mut_ptr(); + let mut has_side: i32 = 0; + let mut stereo_to_mono: i32 = 0; + let mut delay_stack_alloc: i32 = 0; + assert!((*decControl).nChannelsInternal == 1 || (*decControl).nChannelsInternal == 2); + if newPacketFlag != 0 { + n = 0; + while n < (*decControl).nChannelsInternal { + (*channel_state.offset(n as isize)).nFramesDecoded = 0; + n += 1; + } + } + if (*decControl).nChannelsInternal > (*psDec).nChannelsInternal { + ret += silk_init_decoder(&mut *channel_state.offset(1 as isize)); + } + stereo_to_mono = ((*decControl).nChannelsInternal == 1 + && (*psDec).nChannelsInternal == 2 + && (*decControl).internalSampleRate == 1000 * (*channel_state.offset(0 as isize)).fs_kHz) + as i32; + if (*channel_state.offset(0 as isize)).nFramesDecoded == 0 { + n = 0; + while n < (*decControl).nChannelsInternal { + let mut fs_kHz_dec: i32 = 0; + if (*decControl).payloadSize_ms == 0 { + (*channel_state.offset(n as isize)).nFramesPerPacket = 1; + (*channel_state.offset(n as isize)).nb_subfr = 2; + } else if (*decControl).payloadSize_ms == 10 { + (*channel_state.offset(n as isize)).nFramesPerPacket = 1; + (*channel_state.offset(n as isize)).nb_subfr = 2; + } else if (*decControl).payloadSize_ms == 20 { + (*channel_state.offset(n as isize)).nFramesPerPacket = 1; + (*channel_state.offset(n as isize)).nb_subfr = 4; + } else if (*decControl).payloadSize_ms == 40 { + (*channel_state.offset(n as isize)).nFramesPerPacket = 2; + (*channel_state.offset(n as isize)).nb_subfr = 4; + } else if (*decControl).payloadSize_ms == 60 { + (*channel_state.offset(n as isize)).nFramesPerPacket = 3; + (*channel_state.offset(n as isize)).nb_subfr = 4; + } else { + // see comments in `[unsafe_libopus::silk::check_control_input]` + panic!("libopus: assert(0) called"); + // return SILK_DEC_INVALID_FRAME_SIZE; + } + fs_kHz_dec = ((*decControl).internalSampleRate >> 10) + 1; + if fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 { + panic!("libopus: assert(0) called"); + // return SILK_DEC_INVALID_SAMPLING_FREQUENCY; + } + ret += silk_decoder_set_fs( + &mut *channel_state.offset(n as isize), + fs_kHz_dec, + (*decControl).API_sampleRate, + ); + n += 1; + } + } + if (*decControl).nChannelsAPI == 2 + && (*decControl).nChannelsInternal == 2 + && ((*psDec).nChannelsAPI == 1 || (*psDec).nChannelsInternal == 1) + { + memset( + ((*psDec).sStereo.pred_prev_Q13).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 2]>() as u64, + ); + memset( + ((*psDec).sStereo.sSide).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 2]>() as u64, + ); + memcpy( + &mut (*channel_state.offset(1 as isize)).resampler_state as *mut ResamplerState + as *mut core::ffi::c_void, + &mut (*channel_state.offset(0 as isize)).resampler_state as *mut ResamplerState + as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + } + (*psDec).nChannelsAPI = (*decControl).nChannelsAPI; + (*psDec).nChannelsInternal = (*decControl).nChannelsInternal; + if (*decControl).API_sampleRate > MAX_API_FS_KHZ * 1000 || (*decControl).API_sampleRate < 8000 { + ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY; + return ret; + } + if lostFlag != FLAG_PACKET_LOST && (*channel_state.offset(0 as isize)).nFramesDecoded == 0 { + n = 0; + while n < (*decControl).nChannelsInternal { + i = 0; + while i < (*channel_state.offset(n as isize)).nFramesPerPacket { + (*channel_state.offset(n as isize)).VAD_flags[i as usize] = + ec_dec_bit_logp(psRangeDec, 1); + i += 1; + } + (*channel_state.offset(n as isize)).LBRR_flag = ec_dec_bit_logp(psRangeDec, 1); + n += 1; + } + n = 0; + while n < (*decControl).nChannelsInternal { + memset( + ((*channel_state.offset(n as isize)).LBRR_flags).as_mut_ptr() + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 3]>() as u64, + ); + if (*channel_state.offset(n as isize)).LBRR_flag != 0 { + if (*channel_state.offset(n as isize)).nFramesPerPacket == 1 { + (*channel_state.offset(n as isize)).LBRR_flags[0 as usize] = 1; + } else { + LBRR_symbol = ec_dec_icdf( + psRangeDec, + silk_LBRR_flags_iCDF_ptr + [((*channel_state.offset(n as isize)).nFramesPerPacket - 2) as usize], + 8, + ) + 1; + i = 0; + while i < (*channel_state.offset(n as isize)).nFramesPerPacket { + (*channel_state.offset(n as isize)).LBRR_flags[i as usize] = + LBRR_symbol >> i & 1; + i += 1; + } + } + } + n += 1; + } + if lostFlag == FLAG_DECODE_NORMAL { + i = 0; + while i < (*channel_state.offset(0 as isize)).nFramesPerPacket { + n = 0; + while n < (*decControl).nChannelsInternal { + if (*channel_state.offset(n as isize)).LBRR_flags[i as usize] != 0 { + let mut pulses: [i16; 320] = [0; 320]; + let mut condCoding: i32 = 0; + if (*decControl).nChannelsInternal == 2 && n == 0 { + silk_stereo_decode_pred(psRangeDec, MS_pred_Q13.as_mut_ptr()); + if (*channel_state.offset(1 as isize)).LBRR_flags[i as usize] == 0 { + silk_stereo_decode_mid_only(psRangeDec, &mut decode_only_middle); + } + } + if i > 0 + && (*channel_state.offset(n as isize)).LBRR_flags[(i - 1) as usize] != 0 + { + condCoding = CODE_CONDITIONALLY; + } else { + condCoding = CODE_INDEPENDENTLY; + } + silk_decode_indices( + &mut *channel_state.offset(n as isize), + psRangeDec, + i, + 1, + condCoding, + ); + silk_decode_pulses( + psRangeDec, + pulses.as_mut_ptr(), + (*channel_state.offset(n as isize)).indices.signalType as i32, + (*channel_state.offset(n as isize)).indices.quantOffsetType as i32, + (*channel_state.offset(n as isize)).frame_length, + ); + } + n += 1; + } + i += 1; + } + } + } + if (*decControl).nChannelsInternal == 2 { + if lostFlag == FLAG_DECODE_NORMAL + || lostFlag == FLAG_DECODE_LBRR + && (*channel_state.offset(0 as isize)).LBRR_flags + [(*channel_state.offset(0 as isize)).nFramesDecoded as usize] + == 1 + { + silk_stereo_decode_pred(psRangeDec, MS_pred_Q13.as_mut_ptr()); + if lostFlag == FLAG_DECODE_NORMAL + && (*channel_state.offset(1 as isize)).VAD_flags + [(*channel_state.offset(0 as isize)).nFramesDecoded as usize] + == 0 + || lostFlag == FLAG_DECODE_LBRR + && (*channel_state.offset(1 as isize)).LBRR_flags + [(*channel_state.offset(0 as isize)).nFramesDecoded as usize] + == 0 + { + silk_stereo_decode_mid_only(psRangeDec, &mut decode_only_middle); + } else { + decode_only_middle = 0; + } + } else { + n = 0; + while n < 2 { + MS_pred_Q13[n as usize] = (*psDec).sStereo.pred_prev_Q13[n as usize] as i32; + n += 1; + } + } + } + if (*decControl).nChannelsInternal == 2 + && decode_only_middle == 0 + && (*psDec).prev_decode_only_middle == 1 + { + memset( + ((*psDec).channel_state[1 as usize].outBuf).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 480]>() as u64, + ); + memset( + ((*psDec).channel_state[1 as usize].sLPC_Q14_buf).as_mut_ptr() + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 16]>() as u64, + ); + (*psDec).channel_state[1 as usize].lagPrev = 100; + (*psDec).channel_state[1 as usize].LastGainIndex = 10; + (*psDec).channel_state[1 as usize].prevSignalType = TYPE_NO_VOICE_ACTIVITY; + (*psDec).channel_state[1 as usize].first_frame_after_reset = 1; + } + delay_stack_alloc = ((*decControl).internalSampleRate * (*decControl).nChannelsInternal + < (*decControl).API_sampleRate * (*decControl).nChannelsAPI) as i32; + let vla = (if delay_stack_alloc != 0 { + 1 + } else { + (*decControl).nChannelsInternal * ((*channel_state.offset(0 as isize)).frame_length + 2) + }) as usize; + let mut samplesOut1_tmp_storage1: Vec = ::std::vec::from_elem(0, vla); + if delay_stack_alloc != 0 { + samplesOut1_tmp[0 as usize] = samplesOut; + samplesOut1_tmp[1 as usize] = samplesOut + .offset((*channel_state.offset(0 as isize)).frame_length as isize) + .offset(2 as isize); + } else { + samplesOut1_tmp[0 as usize] = samplesOut1_tmp_storage1.as_mut_ptr(); + samplesOut1_tmp[1 as usize] = samplesOut1_tmp_storage1 + .as_mut_ptr() + .offset((*channel_state.offset(0 as isize)).frame_length as isize) + .offset(2 as isize); + } + if lostFlag == FLAG_DECODE_NORMAL { + has_side = (decode_only_middle == 0) as i32; + } else { + has_side = ((*psDec).prev_decode_only_middle == 0 + || (*decControl).nChannelsInternal == 2 + && lostFlag == FLAG_DECODE_LBRR + && (*channel_state.offset(1 as isize)).LBRR_flags + [(*channel_state.offset(1 as isize)).nFramesDecoded as usize] + == 1) as i32; + } + n = 0; + while n < (*decControl).nChannelsInternal { + if n == 0 || has_side != 0 { + let mut FrameIndex: i32 = 0; + let mut condCoding_0: i32 = 0; + FrameIndex = (*channel_state.offset(0 as isize)).nFramesDecoded - n; + if FrameIndex <= 0 { + condCoding_0 = CODE_INDEPENDENTLY; + } else if lostFlag == FLAG_DECODE_LBRR { + condCoding_0 = if (*channel_state.offset(n as isize)).LBRR_flags + [(FrameIndex - 1) as usize] + != 0 + { + CODE_CONDITIONALLY + } else { + CODE_INDEPENDENTLY + }; + } else if n > 0 && (*psDec).prev_decode_only_middle != 0 { + condCoding_0 = CODE_INDEPENDENTLY_NO_LTP_SCALING; + } else { + condCoding_0 = CODE_CONDITIONALLY; + } + ret += silk_decode_frame( + &mut *channel_state.offset(n as isize), + psRangeDec, + &mut *(*samplesOut1_tmp.as_mut_ptr().offset(n as isize)).offset(2 as isize), + &mut nSamplesOutDec, + lostFlag, + condCoding_0, + arch, + ); + } else { + memset( + &mut *(*samplesOut1_tmp.as_mut_ptr().offset(n as isize)).offset(2 as isize) + as *mut i16 as *mut core::ffi::c_void, + 0, + (nSamplesOutDec as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } + let ref mut fresh0 = (*channel_state.offset(n as isize)).nFramesDecoded; + *fresh0 += 1; + n += 1; + } + if (*decControl).nChannelsAPI == 2 && (*decControl).nChannelsInternal == 2 { + silk_stereo_MS_to_LR( + &mut (*psDec).sStereo, + samplesOut1_tmp[0 as usize], + samplesOut1_tmp[1 as usize], + MS_pred_Q13.as_mut_ptr() as *const i32, + (*channel_state.offset(0 as isize)).fs_kHz, + nSamplesOutDec, + ); + } else { + memcpy( + samplesOut1_tmp[0 as usize] as *mut core::ffi::c_void, + ((*psDec).sStereo.sMid).as_mut_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*psDec).sStereo.sMid).as_mut_ptr() as *mut core::ffi::c_void, + &mut *(*samplesOut1_tmp.as_mut_ptr().offset(0 as isize)).offset(nSamplesOutDec as isize) + as *mut i16 as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } + *nSamplesOut = nSamplesOutDec * (*decControl).API_sampleRate + / ((*channel_state.offset(0 as isize)).fs_kHz as i16 as i32 * 1000); + + let vla_0 = (if (*decControl).nChannelsAPI == 2 { + *nSamplesOut + } else { + 1 + }) as usize; + let mut samplesOut2_tmp: Vec = ::std::vec::from_elem(0, vla_0); + + let resample_out_ptr = if (*decControl).nChannelsAPI == 2 { + samplesOut2_tmp.as_mut_slice() + } else { + std::slice::from_raw_parts_mut(samplesOut, *nSamplesOut as usize) + }; + + let vla_1 = (if delay_stack_alloc != 0 { + (*decControl).nChannelsInternal * ((*channel_state.offset(0 as isize)).frame_length + 2) + } else { + 1 + }) as usize; + let mut samplesOut1_tmp_storage2: Vec = ::std::vec::from_elem(0, vla_1); + if delay_stack_alloc != 0 { + memcpy( + samplesOut1_tmp_storage2.as_mut_ptr() as *mut core::ffi::c_void, + samplesOut as *const core::ffi::c_void, + (((*decControl).nChannelsInternal + * ((*channel_state.offset(0 as isize)).frame_length + 2)) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * samplesOut1_tmp_storage2 + .as_mut_ptr() + .offset_from(samplesOut) as i64) as u64, + ), + ); + samplesOut1_tmp[0 as usize] = samplesOut1_tmp_storage2.as_mut_ptr(); + samplesOut1_tmp[1 as usize] = samplesOut1_tmp_storage2 + .as_mut_ptr() + .offset((*channel_state.offset(0 as isize)).frame_length as isize) + .offset(2 as isize); + } + n = 0; + while n + < (if (*decControl).nChannelsAPI < (*decControl).nChannelsInternal { + (*decControl).nChannelsAPI + } else { + (*decControl).nChannelsInternal + }) + { + /* Resample decoded signal to API_sampleRate */ + ret += silk_resampler( + &mut (*channel_state.offset(n as isize)).resampler_state, + resample_out_ptr, + std::slice::from_raw_parts( + &mut *samplesOut1_tmp[n as usize].offset(1 as isize) as *mut i16 as *const i16, + nSamplesOutDec as usize, + ), + ); + if (*decControl).nChannelsAPI == 2 { + i = 0; + while i < *nSamplesOut { + *samplesOut.offset((n + 2 * i) as isize) = resample_out_ptr[i as usize]; + i += 1; + } + } + n += 1; + } + + /* Create two channel output from mono stream */ + if (*decControl).nChannelsAPI == 2 && (*decControl).nChannelsInternal == 1 { + if stereo_to_mono != 0 { + /* Resample right channel for newly collapsed stereo just in case + we weren't doing collapsing when switching to mono */ + ret += silk_resampler( + &mut (*channel_state.offset(1 as isize)).resampler_state, + resample_out_ptr, + std::slice::from_raw_parts( + &mut *samplesOut1_tmp[0].offset(1 as isize) as *mut i16 as *const i16, + nSamplesOutDec as usize, + ), + ); + i = 0; + while i < *nSamplesOut { + *samplesOut.offset((1 + 2 * i) as isize) = resample_out_ptr[i as usize]; + i += 1; + } + } else { + i = 0; + while i < *nSamplesOut { + *samplesOut.offset((1 + 2 * i) as isize) = *samplesOut.offset((0 + 2 * i) as isize); + i += 1; + } + } + } + if (*channel_state.offset(0 as isize)).prevSignalType == TYPE_VOICED { + let mult_tab: [i32; 3] = [6, 4, 3]; + (*decControl).prevPitchLag = (*channel_state.offset(0 as isize)).lagPrev + * mult_tab[((*channel_state.offset(0 as isize)).fs_kHz - 8 >> 2) as usize]; + } else { + (*decControl).prevPitchLag = 0; + } + if lostFlag == FLAG_PACKET_LOST { + i = 0; + while i < (*psDec).nChannelsInternal { + (*psDec).channel_state[i as usize].LastGainIndex = 10; + i += 1; + } + } else { + (*psDec).prev_decode_only_middle = decode_only_middle; + } + return ret; +} diff --git a/vendor/unsafe-libopus/src/silk/decode_core.rs b/vendor/unsafe-libopus/src/silk/decode_core.rs new file mode 100644 index 00000000..14834819 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decode_core.rs @@ -0,0 +1,494 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int32_MAX: i32 = i32::MAX; + pub const silk_int32_MIN: i32 = i32::MIN; +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN, silk_int32_MAX, silk_int32_MIN}; +use crate::externs::{memcpy, memset}; +use crate::silk::define::{ + LTP_ORDER, MAX_LPC_ORDER, MAX_NB_SUBFR, QUANT_LEVEL_ADJUST_Q10, TYPE_VOICED, +}; +use crate::silk::structs::{silk_decoder_control, silk_decoder_state}; +use crate::silk::tables_other::silk_Quantization_Offsets_Q10; +use crate::silk::Inlines::{silk_DIV32_varQ, silk_INVERSE32_varQ}; +use crate::silk::LPC_analysis_filter::silk_LPC_analysis_filter; + +pub unsafe fn silk_decode_core( + psDec: *mut silk_decoder_state, + psDecCtrl: *mut silk_decoder_control, + xq: *mut i16, + pulses: *const i16, + arch: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut lag: i32 = 0; + let mut start_idx: i32 = 0; + let mut sLTP_buf_idx: i32 = 0; + let mut NLSF_interpolation_flag: i32 = 0; + let mut signalType: i32 = 0; + let mut A_Q12: *mut i16 = 0 as *mut i16; + let mut B_Q14: *mut i16 = 0 as *mut i16; + let mut pxq: *mut i16 = 0 as *mut i16; + let mut A_Q12_tmp: [i16; 16] = [0; 16]; + let mut LTP_pred_Q13: i32 = 0; + let mut LPC_pred_Q10: i32 = 0; + let mut Gain_Q10: i32 = 0; + let mut inv_gain_Q31: i32 = 0; + let mut gain_adj_Q16: i32 = 0; + let mut rand_seed: i32 = 0; + let mut offset_Q10: i32 = 0; + let mut pred_lag_ptr: *mut i32 = 0 as *mut i32; + let mut pexc_Q14: *mut i32 = 0 as *mut i32; + let mut pres_Q14: *mut i32 = 0 as *mut i32; + let vla = (*psDec).ltp_mem_length as usize; + let mut sLTP: Vec = ::std::vec::from_elem(0, vla); + let vla_0 = ((*psDec).ltp_mem_length + (*psDec).frame_length) as usize; + let mut sLTP_Q15: Vec = ::std::vec::from_elem(0, vla_0); + let vla_1 = (*psDec).subfr_length as usize; + let mut res_Q14: Vec = ::std::vec::from_elem(0, vla_1); + let vla_2 = ((*psDec).subfr_length + 16) as usize; + let mut sLPC_Q14: Vec = ::std::vec::from_elem(0, vla_2); + offset_Q10 = silk_Quantization_Offsets_Q10[((*psDec).indices.signalType as i32 >> 1) as usize] + [(*psDec).indices.quantOffsetType as usize] as i32; + if ((*psDec).indices.NLSFInterpCoef_Q2 as i32) < (1) << 2 { + NLSF_interpolation_flag = 1; + } else { + NLSF_interpolation_flag = 0; + } + rand_seed = (*psDec).indices.Seed as i32; + i = 0; + while i < (*psDec).frame_length { + rand_seed = 907633515_u32.wrapping_add((rand_seed as u32).wrapping_mul(196314165)) as i32; + (*psDec).exc_Q14[i as usize] = ((*pulses.offset(i as isize) as i32 as u32) << 14) as i32; + if (*psDec).exc_Q14[i as usize] > 0 { + (*psDec).exc_Q14[i as usize] -= QUANT_LEVEL_ADJUST_Q10 << 4; + } else if (*psDec).exc_Q14[i as usize] < 0 { + (*psDec).exc_Q14[i as usize] += QUANT_LEVEL_ADJUST_Q10 << 4; + } + (*psDec).exc_Q14[i as usize] += offset_Q10 << 4; + if rand_seed < 0 { + (*psDec).exc_Q14[i as usize] = -(*psDec).exc_Q14[i as usize]; + } + rand_seed = (rand_seed as u32).wrapping_add(*pulses.offset(i as isize) as u32) as i32; + i += 1; + } + memcpy( + sLPC_Q14.as_mut_ptr() as *mut core::ffi::c_void, + ((*psDec).sLPC_Q14_buf).as_mut_ptr() as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + pexc_Q14 = ((*psDec).exc_Q14).as_mut_ptr(); + pxq = xq; + sLTP_buf_idx = (*psDec).ltp_mem_length; + k = 0; + while k < (*psDec).nb_subfr { + pres_Q14 = res_Q14.as_mut_ptr(); + A_Q12 = ((*psDecCtrl).PredCoef_Q12[(k >> 1) as usize]).as_mut_ptr(); + memcpy( + A_Q12_tmp.as_mut_ptr() as *mut core::ffi::c_void, + A_Q12 as *const core::ffi::c_void, + ((*psDec).LPC_order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + B_Q14 = &mut *((*psDecCtrl).LTPCoef_Q14) + .as_mut_ptr() + .offset((k * LTP_ORDER) as isize) as *mut i16; + signalType = (*psDec).indices.signalType as i32; + Gain_Q10 = (*psDecCtrl).Gains_Q16[k as usize] >> 6; + inv_gain_Q31 = silk_INVERSE32_varQ((*psDecCtrl).Gains_Q16[k as usize], 47); + if (*psDecCtrl).Gains_Q16[k as usize] != (*psDec).prev_gain_Q16 { + gain_adj_Q16 = silk_DIV32_varQ( + (*psDec).prev_gain_Q16, + (*psDecCtrl).Gains_Q16[k as usize], + 16, + ); + i = 0; + while i < MAX_LPC_ORDER { + *sLPC_Q14.as_mut_ptr().offset(i as isize) = (gain_adj_Q16 as i64 + * *sLPC_Q14.as_mut_ptr().offset(i as isize) as i64 + >> 16) as i32; + i += 1; + } + } else { + gain_adj_Q16 = (1) << 16; + } + (*psDec).prev_gain_Q16 = (*psDecCtrl).Gains_Q16[k as usize]; + if (*psDec).lossCnt != 0 + && (*psDec).prevSignalType == TYPE_VOICED + && (*psDec).indices.signalType as i32 != TYPE_VOICED + && k < MAX_NB_SUBFR / 2 + { + memset( + B_Q14 as *mut core::ffi::c_void, + 0, + 5_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + *B_Q14.offset((LTP_ORDER / 2) as isize) = + (0.25f64 * ((1) << 14) as f64 + 0.5f64) as i32 as i16; + signalType = TYPE_VOICED; + (*psDecCtrl).pitchL[k as usize] = (*psDec).lagPrev; + } + if signalType == TYPE_VOICED { + lag = (*psDecCtrl).pitchL[k as usize]; + if k == 0 || k == 2 && NLSF_interpolation_flag != 0 { + start_idx = (*psDec).ltp_mem_length - lag - (*psDec).LPC_order - LTP_ORDER / 2; + assert!(start_idx > 0); + if k == 2 { + memcpy( + &mut *((*psDec).outBuf) + .as_mut_ptr() + .offset((*psDec).ltp_mem_length as isize) + as *mut i16 as *mut core::ffi::c_void, + xq as *const core::ffi::c_void, + ((2 * (*psDec).subfr_length) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + } + silk_LPC_analysis_filter( + &mut *sLTP.as_mut_ptr().offset(start_idx as isize), + &mut *((*psDec).outBuf) + .as_mut_ptr() + .offset((start_idx + k * (*psDec).subfr_length) as isize), + A_Q12, + (*psDec).ltp_mem_length - start_idx, + (*psDec).LPC_order, + arch, + ); + if k == 0 { + inv_gain_Q31 = (((inv_gain_Q31 as i64 + * (*psDecCtrl).LTP_scale_Q14 as i16 as i64 + >> 16) as i32 as u32) + << 2) as i32; + } + i = 0; + while i < lag + LTP_ORDER / 2 { + *sLTP_Q15 + .as_mut_ptr() + .offset((sLTP_buf_idx - i - 1) as isize) = (inv_gain_Q31 as i64 + * *sLTP + .as_mut_ptr() + .offset(((*psDec).ltp_mem_length - i - 1) as isize) + as i64 + >> 16) + as i32; + i += 1; + } + } else if gain_adj_Q16 != (1) << 16 { + i = 0; + while i < lag + LTP_ORDER / 2 { + *sLTP_Q15 + .as_mut_ptr() + .offset((sLTP_buf_idx - i - 1) as isize) = (gain_adj_Q16 as i64 + * *sLTP_Q15 + .as_mut_ptr() + .offset((sLTP_buf_idx - i - 1) as isize) + as i64 + >> 16) + as i32; + i += 1; + } + } + } + if signalType == TYPE_VOICED { + pred_lag_ptr = &mut *sLTP_Q15 + .as_mut_ptr() + .offset((sLTP_buf_idx - lag + LTP_ORDER / 2) as isize) + as *mut i32; + i = 0; + while i < (*psDec).subfr_length { + LTP_pred_Q13 = 2; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(0 as isize) as i64 * *B_Q14.offset(0 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-1 as isize) as i64 * *B_Q14.offset(1 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-(2) as isize) as i64 + * *B_Q14.offset(2 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-(3) as isize) as i64 + * *B_Q14.offset(3 as isize) as i64 + >> 16)) as i32; + LTP_pred_Q13 = (LTP_pred_Q13 as i64 + + (*pred_lag_ptr.offset(-(4) as isize) as i64 + * *B_Q14.offset(4 as isize) as i64 + >> 16)) as i32; + pred_lag_ptr = pred_lag_ptr.offset(1); + *pres_Q14.offset(i as isize) = + *pexc_Q14.offset(i as isize) + ((LTP_pred_Q13 as u32) << 1) as i32; + *sLTP_Q15.as_mut_ptr().offset(sLTP_buf_idx as isize) = + ((*pres_Q14.offset(i as isize) as u32) << 1) as i32; + sLTP_buf_idx += 1; + i += 1; + } + } else { + pres_Q14 = pexc_Q14; + } + i = 0; + while i < (*psDec).subfr_length { + assert!((*psDec).LPC_order == 10 || (*psDec).LPC_order == 16); + LPC_pred_Q10 = (*psDec).LPC_order >> 1; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 1) as isize) as i64 + * A_Q12_tmp[0 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 2) as isize) as i64 + * A_Q12_tmp[1 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 3) as isize) as i64 + * A_Q12_tmp[2 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 4) as isize) as i64 + * A_Q12_tmp[3 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 5) as isize) as i64 + * A_Q12_tmp[4 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 6) as isize) as i64 + * A_Q12_tmp[5 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 7) as isize) as i64 + * A_Q12_tmp[6 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 8) as isize) as i64 + * A_Q12_tmp[7 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 9) as isize) as i64 + * A_Q12_tmp[8 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 10) as isize) as i64 + * A_Q12_tmp[9 as usize] as i64 + >> 16)) as i32; + if (*psDec).LPC_order == 16 { + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 11) as isize) as i64 + * A_Q12_tmp[10 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 12) as isize) as i64 + * A_Q12_tmp[11 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 13) as isize) as i64 + * A_Q12_tmp[12 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 14) as isize) as i64 + * A_Q12_tmp[13 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 15) as isize) as i64 + * A_Q12_tmp[14 as usize] as i64 + >> 16)) as i32; + LPC_pred_Q10 = (LPC_pred_Q10 as i64 + + (*sLPC_Q14.as_mut_ptr().offset((16 + i - 16) as isize) as i64 + * A_Q12_tmp[15 as usize] as i64 + >> 16)) as i32; + } + *sLPC_Q14.as_mut_ptr().offset((MAX_LPC_ORDER + i) as isize) = + if (*pres_Q14.offset(i as isize) as u32).wrapping_add( + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 as u32, + ) & 0x80000000 as u32 + == 0 + { + if (*pres_Q14.offset(i as isize) + & (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32) as u32 + & 0x80000000 as u32 + != 0 + { + silk_int32_MIN as i32 + } else { + *pres_Q14.offset(i as isize) + + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 + } + } else if (*pres_Q14.offset(i as isize) + | (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32) as u32 + & 0x80000000 as u32 + == 0 + { + silk_int32_MAX + } else { + *pres_Q14.offset(i as isize) + + (((if 0x80000000 as u32 as i32 >> 4 > 0x7fffffff >> 4 { + if LPC_pred_Q10 > 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + if LPC_pred_Q10 < 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + LPC_pred_Q10 + } + } + } else { + if LPC_pred_Q10 > 0x7fffffff >> 4 { + 0x7fffffff >> 4 + } else { + if LPC_pred_Q10 < 0x80000000 as u32 as i32 >> 4 { + 0x80000000 as u32 as i32 >> 4 + } else { + LPC_pred_Q10 + } + } + }) as u32) + << 4) as i32 + }; + *pxq.offset(i as isize) = (if (if 8 == 1 { + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 >> 16) + as i32 + >> 1) + + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 >> 16) + as i32 + >> 8 - 1) + + 1 + >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 >> 16) + as i32 + >> 1) + + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 >> 16) + as i32 + >> 8 - 1) + + 1 + >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 >> 16) + as i32 + >> 1) + + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 + >> 16) as i32 + & 1) + } else { + ((*sLPC_Q14.as_mut_ptr().offset((16 + i) as isize) as i64 * Gain_Q10 as i64 >> 16) + as i32 + >> 8 - 1) + + 1 + >> 1 + }) as i16; + i += 1; + } + memcpy( + sLPC_Q14.as_mut_ptr() as *mut core::ffi::c_void, + &mut *sLPC_Q14.as_mut_ptr().offset((*psDec).subfr_length as isize) as *mut i32 + as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + pexc_Q14 = pexc_Q14.offset((*psDec).subfr_length as isize); + pxq = pxq.offset((*psDec).subfr_length as isize); + k += 1; + } + memcpy( + ((*psDec).sLPC_Q14_buf).as_mut_ptr() as *mut core::ffi::c_void, + sLPC_Q14.as_mut_ptr() as *const core::ffi::c_void, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); +} diff --git a/vendor/unsafe-libopus/src/silk/decode_frame.rs b/vendor/unsafe-libopus/src/silk/decode_frame.rs new file mode 100644 index 00000000..c0266c06 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decode_frame.rs @@ -0,0 +1,91 @@ +use crate::celt::entdec::ec_dec; +use crate::externs::{memcpy, memmove}; +use crate::silk::dec_API::{FLAG_DECODE_LBRR, FLAG_DECODE_NORMAL}; +use crate::silk::decode_core::silk_decode_core; +use crate::silk::decode_indices::silk_decode_indices; +use crate::silk::decode_parameters::silk_decode_parameters; +use crate::silk::decode_pulses::silk_decode_pulses; +use crate::silk::structs::{silk_decoder_control, silk_decoder_state}; +use crate::silk::CNG::silk_CNG; +use crate::silk::PLC::{silk_PLC, silk_PLC_glue_frames}; + +pub unsafe fn silk_decode_frame( + psDec: *mut silk_decoder_state, + psRangeDec: &mut ec_dec, + pOut: *mut i16, + pN: *mut i32, + lostFlag: i32, + condCoding: i32, + arch: i32, +) -> i32 { + let mut L: i32 = 0; + let mut mv_len: i32 = 0; + let ret: i32 = 0; + L = (*psDec).frame_length; + let mut psDecCtrl: [silk_decoder_control; 1] = [silk_decoder_control { + pitchL: [0; 4], + Gains_Q16: [0; 4], + PredCoef_Q12: [[0; 16]; 2], + LTPCoef_Q14: [0; 20], + LTP_scale_Q14: 0, + }; 1]; + (*psDecCtrl.as_mut_ptr()).LTP_scale_Q14 = 0; + assert!(L > 0 && L <= 5 * 4 * 16); + if lostFlag == FLAG_DECODE_NORMAL + || lostFlag == FLAG_DECODE_LBRR + && (*psDec).LBRR_flags[(*psDec).nFramesDecoded as usize] == 1 + { + let vla = (L + 16 - 1 & !(16 - 1)) as usize; + let mut pulses: Vec = ::std::vec::from_elem(0, vla); + silk_decode_indices( + psDec, + psRangeDec, + (*psDec).nFramesDecoded, + lostFlag, + condCoding, + ); + silk_decode_pulses( + psRangeDec, + pulses.as_mut_ptr(), + (*psDec).indices.signalType as i32, + (*psDec).indices.quantOffsetType as i32, + (*psDec).frame_length, + ); + silk_decode_parameters(psDec, psDecCtrl.as_mut_ptr(), condCoding); + silk_decode_core( + psDec, + psDecCtrl.as_mut_ptr(), + pOut, + pulses.as_mut_ptr() as *const i16, + arch, + ); + silk_PLC(psDec, psDecCtrl.as_mut_ptr(), pOut, 0, arch); + (*psDec).lossCnt = 0; + (*psDec).prevSignalType = (*psDec).indices.signalType as i32; + assert!((*psDec).prevSignalType >= 0 && (*psDec).prevSignalType <= 2); + (*psDec).first_frame_after_reset = 0; + } else { + (*psDec).indices.signalType = (*psDec).prevSignalType as i8; + silk_PLC(psDec, psDecCtrl.as_mut_ptr(), pOut, 1, arch); + } + assert!((*psDec).ltp_mem_length >= (*psDec).frame_length); + mv_len = (*psDec).ltp_mem_length - (*psDec).frame_length; + memmove( + ((*psDec).outBuf).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psDec).outBuf) + .as_mut_ptr() + .offset((*psDec).frame_length as isize) as *mut i16 as *const core::ffi::c_void, + (mv_len as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + &mut *((*psDec).outBuf).as_mut_ptr().offset(mv_len as isize) as *mut i16 + as *mut core::ffi::c_void, + pOut as *const core::ffi::c_void, + ((*psDec).frame_length as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + silk_CNG(psDec, psDecCtrl.as_mut_ptr(), pOut, L); + silk_PLC_glue_frames(psDec, pOut, L); + (*psDec).lagPrev = (*psDecCtrl.as_mut_ptr()).pitchL[((*psDec).nb_subfr - 1) as usize]; + *pN = L; + return ret; +} diff --git a/vendor/unsafe-libopus/src/silk/decode_indices.rs b/vendor/unsafe-libopus/src/silk/decode_indices.rs new file mode 100644 index 00000000..269e1b85 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decode_indices.rs @@ -0,0 +1,132 @@ +use crate::celt::entdec::{ec_dec, ec_dec_icdf}; +use crate::silk::define::{ + CODE_CONDITIONALLY, CODE_INDEPENDENTLY, MAX_NB_SUBFR, NLSF_QUANT_MAX_AMPLITUDE, TYPE_VOICED, +}; +use crate::silk::structs::silk_decoder_state; +use crate::silk::tables_LTP::{silk_LTP_gain_iCDF_ptrs, silk_LTP_per_index_iCDF}; +use crate::silk::tables_gain::{silk_delta_gain_iCDF, silk_gain_iCDF}; +use crate::silk::tables_other::{ + silk_LTPscale_iCDF, silk_NLSF_EXT_iCDF, silk_NLSF_interpolation_factor_iCDF, + silk_type_offset_VAD_iCDF, silk_type_offset_no_VAD_iCDF, silk_uniform4_iCDF, + silk_uniform8_iCDF, +}; +use crate::silk::tables_pitch_lag::{silk_pitch_delta_iCDF, silk_pitch_lag_iCDF}; +use crate::silk::NLSF_unpack::silk_NLSF_unpack; + +pub unsafe fn silk_decode_indices( + psDec: *mut silk_decoder_state, + psRangeDec: &mut ec_dec, + FrameIndex: i32, + decode_LBRR: i32, + condCoding: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut Ix: i32 = 0; + let mut decode_absolute_lagIndex: i32 = 0; + let mut delta_lagIndex: i32 = 0; + let mut ec_ix: [i16; 16] = [0; 16]; + let mut pred_Q8: [u8; 16] = [0; 16]; + if decode_LBRR != 0 || (*psDec).VAD_flags[FrameIndex as usize] != 0 { + Ix = ec_dec_icdf(psRangeDec, &silk_type_offset_VAD_iCDF, 8) + 2; + } else { + Ix = ec_dec_icdf(psRangeDec, &silk_type_offset_no_VAD_iCDF, 8); + } + (*psDec).indices.signalType = (Ix >> 1) as i8; + (*psDec).indices.quantOffsetType = (Ix & 1) as i8; + if condCoding == CODE_CONDITIONALLY { + (*psDec).indices.GainsIndices[0 as usize] = + ec_dec_icdf(psRangeDec, &silk_delta_gain_iCDF, 8) as i8; + } else { + (*psDec).indices.GainsIndices[0 as usize] = ((ec_dec_icdf( + psRangeDec, + &silk_gain_iCDF[(*psDec).indices.signalType as usize], + 8, + ) as u32) + << 3) as i32 as i8; + (*psDec).indices.GainsIndices[0 as usize] = + ((*psDec).indices.GainsIndices[0 as usize] as i32 + + ec_dec_icdf(psRangeDec, &silk_uniform8_iCDF, 8) as i8 as i32) as i8; + } + i = 1; + while i < (*psDec).nb_subfr { + (*psDec).indices.GainsIndices[i as usize] = + ec_dec_icdf(psRangeDec, &silk_delta_gain_iCDF, 8) as i8; + i += 1; + } + (*psDec).indices.NLSFIndices[0 as usize] = ec_dec_icdf( + psRangeDec, + &(*(*psDec).psNLSF_CB).CB1_iCDF[(((*psDec).indices.signalType as i32 >> 1) + * (*(*psDec).psNLSF_CB).nVectors as i32) + as usize..], + 8, + ) as i8; + silk_NLSF_unpack( + &mut ec_ix, + &mut pred_Q8, + (*psDec).psNLSF_CB, + (*psDec).indices.NLSFIndices[0 as usize] as i32, + ); + assert!((*(*psDec).psNLSF_CB).order as i32 == (*psDec).LPC_order); + i = 0; + while i < (*(*psDec).psNLSF_CB).order as i32 { + Ix = ec_dec_icdf( + psRangeDec, + &(*(*psDec).psNLSF_CB).ec_iCDF[*ec_ix.as_mut_ptr().offset(i as isize) as usize..], + 8, + ); + if Ix == 0 { + Ix -= ec_dec_icdf(psRangeDec, &silk_NLSF_EXT_iCDF, 8); + } else if Ix == 2 * NLSF_QUANT_MAX_AMPLITUDE { + Ix += ec_dec_icdf(psRangeDec, &silk_NLSF_EXT_iCDF, 8); + } + (*psDec).indices.NLSFIndices[(i + 1) as usize] = (Ix - NLSF_QUANT_MAX_AMPLITUDE) as i8; + i += 1; + } + if (*psDec).nb_subfr == MAX_NB_SUBFR { + (*psDec).indices.NLSFInterpCoef_Q2 = + ec_dec_icdf(psRangeDec, &silk_NLSF_interpolation_factor_iCDF, 8) as i8; + } else { + (*psDec).indices.NLSFInterpCoef_Q2 = 4; + } + if (*psDec).indices.signalType as i32 == TYPE_VOICED { + decode_absolute_lagIndex = 1; + if condCoding == CODE_CONDITIONALLY && (*psDec).ec_prevSignalType == TYPE_VOICED { + delta_lagIndex = ec_dec_icdf(psRangeDec, &silk_pitch_delta_iCDF, 8) as i16 as i32; + if delta_lagIndex > 0 { + delta_lagIndex = delta_lagIndex - 9; + (*psDec).indices.lagIndex = + ((*psDec).ec_prevLagIndex as i32 + delta_lagIndex) as i16; + decode_absolute_lagIndex = 0; + } + } + if decode_absolute_lagIndex != 0 { + (*psDec).indices.lagIndex = (ec_dec_icdf(psRangeDec, &silk_pitch_lag_iCDF, 8) as i16 + as i32 + * ((*psDec).fs_kHz >> 1)) as i16; + (*psDec).indices.lagIndex = ((*psDec).indices.lagIndex as i32 + + ec_dec_icdf(psRangeDec, (*psDec).pitch_lag_low_bits_iCDF, 8) as i16 as i32) + as i16; + } + (*psDec).ec_prevLagIndex = (*psDec).indices.lagIndex; + (*psDec).indices.contourIndex = + ec_dec_icdf(psRangeDec, (*psDec).pitch_contour_iCDF, 8) as i8; + (*psDec).indices.PERIndex = ec_dec_icdf(psRangeDec, &silk_LTP_per_index_iCDF, 8) as i8; + k = 0; + while k < (*psDec).nb_subfr { + (*psDec).indices.LTPIndex[k as usize] = ec_dec_icdf( + psRangeDec, + silk_LTP_gain_iCDF_ptrs[(*psDec).indices.PERIndex as usize], + 8, + ) as i8; + k += 1; + } + if condCoding == CODE_INDEPENDENTLY { + (*psDec).indices.LTP_scaleIndex = ec_dec_icdf(psRangeDec, &silk_LTPscale_iCDF, 8) as i8; + } else { + (*psDec).indices.LTP_scaleIndex = 0; + } + } + (*psDec).ec_prevSignalType = (*psDec).indices.signalType as i32; + (*psDec).indices.Seed = ec_dec_icdf(psRangeDec, &silk_uniform4_iCDF, 8) as i8; +} diff --git a/vendor/unsafe-libopus/src/silk/decode_parameters.rs b/vendor/unsafe-libopus/src/silk/decode_parameters.rs new file mode 100644 index 00000000..6eff58aa --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decode_parameters.rs @@ -0,0 +1,119 @@ +use crate::externs::{memcpy, memset}; +use crate::silk::bwexpander::silk_bwexpander; +use crate::silk::decode_pitch::silk_decode_pitch; +use crate::silk::define::{BWE_AFTER_LOSS_Q16, CODE_CONDITIONALLY, LTP_ORDER, TYPE_VOICED}; +use crate::silk::gain_quant::silk_gains_dequant; +use crate::silk::structs::{silk_decoder_control, silk_decoder_state}; +use crate::silk::tables_LTP::silk_LTP_vq_ptrs_Q7; +use crate::silk::tables_other::silk_LTPScales_table_Q14; +use crate::silk::NLSF_decode::silk_NLSF_decode; +use crate::silk::NLSF2A::silk_NLSF2A; + +pub unsafe fn silk_decode_parameters( + psDec: *mut silk_decoder_state, + psDecCtrl: *mut silk_decoder_control, + condCoding: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut Ix: i32 = 0; + let mut pNLSF_Q15: [i16; 16] = [0; 16]; + let mut pNLSF0_Q15: [i16; 16] = [0; 16]; + let mut cbk_ptr_Q7: *const i8 = 0 as *const i8; + silk_gains_dequant( + ((*psDecCtrl).Gains_Q16).as_mut_ptr(), + ((*psDec).indices.GainsIndices).as_mut_ptr() as *const i8, + &mut (*psDec).LastGainIndex, + (condCoding == CODE_CONDITIONALLY) as i32, + (*psDec).nb_subfr, + ); + silk_NLSF_decode( + &mut pNLSF_Q15[..(*psDec).psNLSF_CB.order as usize], + &(*psDec).indices.NLSFIndices[..(*psDec).psNLSF_CB.order as usize + 1], + (*psDec).psNLSF_CB, + ); + silk_NLSF2A( + ((*psDecCtrl).PredCoef_Q12[1 as usize]).as_mut_ptr(), + pNLSF_Q15.as_mut_ptr(), + (*psDec).LPC_order, + (*psDec).arch, + ); + if (*psDec).first_frame_after_reset == 1 { + (*psDec).indices.NLSFInterpCoef_Q2 = 4; + } + if ((*psDec).indices.NLSFInterpCoef_Q2 as i32) < 4 { + i = 0; + while i < (*psDec).LPC_order { + pNLSF0_Q15[i as usize] = ((*psDec).prevNLSF_Q15[i as usize] as i32 + + ((*psDec).indices.NLSFInterpCoef_Q2 as i32 + * (pNLSF_Q15[i as usize] as i32 - (*psDec).prevNLSF_Q15[i as usize] as i32) + >> 2)) as i16; + i += 1; + } + silk_NLSF2A( + ((*psDecCtrl).PredCoef_Q12[0 as usize]).as_mut_ptr(), + pNLSF0_Q15.as_mut_ptr(), + (*psDec).LPC_order, + (*psDec).arch, + ); + } else { + memcpy( + ((*psDecCtrl).PredCoef_Q12[0 as usize]).as_mut_ptr() as *mut core::ffi::c_void, + ((*psDecCtrl).PredCoef_Q12[1 as usize]).as_mut_ptr() as *const core::ffi::c_void, + ((*psDec).LPC_order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } + memcpy( + ((*psDec).prevNLSF_Q15).as_mut_ptr() as *mut core::ffi::c_void, + pNLSF_Q15.as_mut_ptr() as *const core::ffi::c_void, + ((*psDec).LPC_order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + if (*psDec).lossCnt != 0 { + silk_bwexpander( + ((*psDecCtrl).PredCoef_Q12[0 as usize]).as_mut_ptr(), + (*psDec).LPC_order, + BWE_AFTER_LOSS_Q16, + ); + silk_bwexpander( + ((*psDecCtrl).PredCoef_Q12[1 as usize]).as_mut_ptr(), + (*psDec).LPC_order, + BWE_AFTER_LOSS_Q16, + ); + } + if (*psDec).indices.signalType as i32 == TYPE_VOICED { + silk_decode_pitch( + (*psDec).indices.lagIndex, + (*psDec).indices.contourIndex, + ((*psDecCtrl).pitchL).as_mut_ptr(), + (*psDec).fs_kHz, + (*psDec).nb_subfr, + ); + cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[(*psDec).indices.PERIndex as usize]; + k = 0; + while k < (*psDec).nb_subfr { + Ix = (*psDec).indices.LTPIndex[k as usize] as i32; + i = 0; + while i < LTP_ORDER { + (*psDecCtrl).LTPCoef_Q14[(k * LTP_ORDER + i) as usize] = + ((*cbk_ptr_Q7.offset((Ix * 5 + i) as isize) as u32) << 7) as i32 as i16; + i += 1; + } + k += 1; + } + Ix = (*psDec).indices.LTP_scaleIndex as i32; + (*psDecCtrl).LTP_scale_Q14 = silk_LTPScales_table_Q14[Ix as usize] as i32; + } else { + memset( + ((*psDecCtrl).pitchL).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ((*psDec).nb_subfr as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + memset( + ((*psDecCtrl).LTPCoef_Q14).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ((5 * (*psDec).nb_subfr) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psDec).indices.PERIndex = 0; + (*psDecCtrl).LTP_scale_Q14 = 0; + }; +} diff --git a/vendor/unsafe-libopus/src/silk/decode_pitch.rs b/vendor/unsafe-libopus/src/silk/decode_pitch.rs new file mode 100644 index 00000000..97837dd3 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decode_pitch.rs @@ -0,0 +1,69 @@ +use crate::silk::pitch_est_tables::{ + silk_CB_lags_stage2, silk_CB_lags_stage2_10_ms, silk_CB_lags_stage3, silk_CB_lags_stage3_10_ms, + PE_MAX_NB_SUBFR, PE_NB_CBKS_STAGE2_10MS, PE_NB_CBKS_STAGE2_EXT, PE_NB_CBKS_STAGE3_10MS, + PE_NB_CBKS_STAGE3_MAX, +}; + +pub unsafe fn silk_decode_pitch( + lagIndex: i16, + contourIndex: i8, + pitch_lags: *mut i32, + Fs_kHz: i32, + nb_subfr: i32, +) { + let mut lag: i32 = 0; + let mut k: i32 = 0; + let mut min_lag: i32 = 0; + let mut max_lag: i32 = 0; + let mut cbk_size: i32 = 0; + let mut Lag_CB_ptr: *const i8 = 0 as *const i8; + if Fs_kHz == 8 { + if nb_subfr == PE_MAX_NB_SUBFR { + Lag_CB_ptr = &*(*silk_CB_lags_stage2.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + cbk_size = PE_NB_CBKS_STAGE2_EXT; + } else { + assert!(nb_subfr == 4 >> 1); + Lag_CB_ptr = &*(*silk_CB_lags_stage2_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + cbk_size = PE_NB_CBKS_STAGE2_10MS; + } + } else if nb_subfr == PE_MAX_NB_SUBFR { + Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + assert!(nb_subfr == 4 >> 1); + Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + min_lag = 2 * Fs_kHz as i16 as i32; + max_lag = 18 * Fs_kHz as i16 as i32; + lag = min_lag + lagIndex as i32; + k = 0; + while k < nb_subfr { + *pitch_lags.offset(k as isize) = + lag + *Lag_CB_ptr.offset((k * cbk_size + contourIndex as i32) as isize) as i32; + *pitch_lags.offset(k as isize) = if min_lag > max_lag { + if *pitch_lags.offset(k as isize) > min_lag { + min_lag + } else if *pitch_lags.offset(k as isize) < max_lag { + max_lag + } else { + *pitch_lags.offset(k as isize) + } + } else if *pitch_lags.offset(k as isize) > max_lag { + max_lag + } else if *pitch_lags.offset(k as isize) < min_lag { + min_lag + } else { + *pitch_lags.offset(k as isize) + }; + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/decode_pulses.rs b/vendor/unsafe-libopus/src/silk/decode_pulses.rs new file mode 100644 index 00000000..2b6c8c16 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decode_pulses.rs @@ -0,0 +1,102 @@ +use crate::celt::entdec::{ec_dec, ec_dec_icdf}; +use crate::externs::memset; +use crate::silk::code_signs::silk_decode_signs; +use crate::silk::define::{N_RATE_LEVELS, SHELL_CODEC_FRAME_LENGTH, SILK_MAX_PULSES}; +use crate::silk::shell_coder::silk_shell_decoder; +use crate::silk::tables_other::silk_lsb_iCDF; +use crate::silk::tables_pulses_per_block::{silk_pulses_per_block_iCDF, silk_rate_levels_iCDF}; + +pub unsafe fn silk_decode_pulses( + psRangeDec: &mut ec_dec, + pulses: *mut i16, + signalType: i32, + quantOffsetType: i32, + frame_length: i32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + let mut iter: i32 = 0; + let mut abs_q: i32 = 0; + let mut nLS: i32 = 0; + let mut RateLevelIndex: i32 = 0; + let mut sum_pulses: [i32; 20] = [0; 20]; + let mut nLshifts: [i32; 20] = [0; 20]; + let mut pulses_ptr: *mut i16 = 0 as *mut i16; + RateLevelIndex = ec_dec_icdf( + psRangeDec, + &(silk_rate_levels_iCDF[(signalType >> 1) as usize]), + 8, + ); + iter = frame_length >> 4; + if iter * SHELL_CODEC_FRAME_LENGTH < frame_length { + assert!(frame_length == 12 * 10); + iter += 1; + } + let cdf_ptr = &silk_pulses_per_block_iCDF[RateLevelIndex as usize]; + i = 0; + while i < iter { + nLshifts[i as usize] = 0; + sum_pulses[i as usize] = ec_dec_icdf(psRangeDec, cdf_ptr, 8); + while sum_pulses[i as usize] == SILK_MAX_PULSES + 1 { + nLshifts[i as usize] += 1; + sum_pulses[i as usize] = ec_dec_icdf( + psRangeDec, + &silk_pulses_per_block_iCDF[(N_RATE_LEVELS - 1) as usize] + [(nLshifts[i as usize] == 10) as i32 as usize..], + 8, + ); + } + i += 1; + } + i = 0; + while i < iter { + if sum_pulses[i as usize] > 0 { + silk_shell_decoder( + std::slice::from_raw_parts_mut( + &mut *pulses.offset((i as i16 as i32 * 16) as isize), + SHELL_CODEC_FRAME_LENGTH as usize, + ), + psRangeDec, + sum_pulses[i as usize], + ); + } else { + memset( + &mut *pulses.offset((i as i16 as i32 * 16) as isize) as *mut i16 + as *mut core::ffi::c_void, + 0, + 16_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } + i += 1; + } + i = 0; + while i < iter { + if nLshifts[i as usize] > 0 { + nLS = nLshifts[i as usize]; + pulses_ptr = &mut *pulses.offset((i as i16 as i32 * 16) as isize) as *mut i16; + k = 0; + while k < SHELL_CODEC_FRAME_LENGTH { + abs_q = *pulses_ptr.offset(k as isize) as i32; + j = 0; + while j < nLS { + abs_q = ((abs_q as u32) << 1) as i32; + abs_q += ec_dec_icdf(psRangeDec, &silk_lsb_iCDF, 8); + j += 1; + } + *pulses_ptr.offset(k as isize) = abs_q as i16; + k += 1; + } + sum_pulses[i as usize] |= nLS << 5; + } + i += 1; + } + silk_decode_signs( + psRangeDec, + pulses, + frame_length, + signalType, + quantOffsetType, + sum_pulses.as_mut_ptr() as *const i32, + ); +} diff --git a/vendor/unsafe-libopus/src/silk/decoder_set_fs.rs b/vendor/unsafe-libopus/src/silk/decoder_set_fs.rs new file mode 100644 index 00000000..c5c7bf96 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/decoder_set_fs.rs @@ -0,0 +1,78 @@ +use crate::externs::memset; +use crate::silk::define::{MAX_LPC_ORDER, MAX_NB_SUBFR, MIN_LPC_ORDER, TYPE_NO_VOICE_ACTIVITY}; +use crate::silk::resampler::silk_resampler_init; +use crate::silk::structs::silk_decoder_state; +use crate::silk::tables_NLSF_CB_NB_MB::silk_NLSF_CB_NB_MB; +use crate::silk::tables_NLSF_CB_WB::silk_NLSF_CB_WB; +use crate::silk::tables_other::{silk_uniform4_iCDF, silk_uniform6_iCDF, silk_uniform8_iCDF}; +use crate::silk::tables_pitch_lag::{ + silk_pitch_contour_10_ms_NB_iCDF, silk_pitch_contour_10_ms_iCDF, silk_pitch_contour_NB_iCDF, + silk_pitch_contour_iCDF, +}; + +pub unsafe fn silk_decoder_set_fs( + psDec: *mut silk_decoder_state, + fs_kHz: i32, + fs_API_Hz: i32, +) -> i32 { + let mut frame_length: i32 = 0; + assert!(fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16); + assert!((*psDec).nb_subfr == 4 || (*psDec).nb_subfr == 4 / 2); + (*psDec).subfr_length = 5 * fs_kHz as i16 as i32; + frame_length = (*psDec).nb_subfr as i16 as i32 * (*psDec).subfr_length as i16 as i32; + if (*psDec).fs_kHz != fs_kHz || (*psDec).fs_API_hz != fs_API_Hz { + (*psDec).resampler_state = silk_resampler_init(fs_kHz as i16 as i32 * 1000, fs_API_Hz, 0); + (*psDec).fs_API_hz = fs_API_Hz; + } + if (*psDec).fs_kHz != fs_kHz || frame_length != (*psDec).frame_length { + if fs_kHz == 8 { + if (*psDec).nb_subfr == MAX_NB_SUBFR { + (*psDec).pitch_contour_iCDF = &silk_pitch_contour_NB_iCDF; + } else { + (*psDec).pitch_contour_iCDF = &silk_pitch_contour_10_ms_NB_iCDF; + } + } else if (*psDec).nb_subfr == MAX_NB_SUBFR { + (*psDec).pitch_contour_iCDF = &silk_pitch_contour_iCDF; + } else { + (*psDec).pitch_contour_iCDF = &silk_pitch_contour_10_ms_iCDF; + } + if (*psDec).fs_kHz != fs_kHz { + (*psDec).ltp_mem_length = 20 * fs_kHz as i16 as i32; + if fs_kHz == 8 || fs_kHz == 12 { + (*psDec).LPC_order = MIN_LPC_ORDER; + (*psDec).psNLSF_CB = &silk_NLSF_CB_NB_MB; + } else { + (*psDec).LPC_order = MAX_LPC_ORDER; + (*psDec).psNLSF_CB = &silk_NLSF_CB_WB; + } + if fs_kHz == 16 { + (*psDec).pitch_lag_low_bits_iCDF = &silk_uniform8_iCDF; + } else if fs_kHz == 12 { + (*psDec).pitch_lag_low_bits_iCDF = &silk_uniform6_iCDF; + } else if fs_kHz == 8 { + (*psDec).pitch_lag_low_bits_iCDF = &silk_uniform4_iCDF; + } else { + panic!("libopus: assert(0) called"); + } + (*psDec).first_frame_after_reset = 1; + (*psDec).lagPrev = 100; + (*psDec).LastGainIndex = 10; + (*psDec).prevSignalType = TYPE_NO_VOICE_ACTIVITY; + memset( + ((*psDec).outBuf).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 480]>() as u64, + ); + memset( + ((*psDec).sLPC_Q14_buf).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 16]>() as u64, + ); + } + (*psDec).fs_kHz = fs_kHz; + (*psDec).frame_length = frame_length; + } + assert!((*psDec).frame_length > 0 && (*psDec).frame_length <= 5 * 4 * 16); + + return 0; +} diff --git a/vendor/unsafe-libopus/src/silk/define.rs b/vendor/unsafe-libopus/src/silk/define.rs new file mode 100644 index 00000000..8baa0e0c --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/define.rs @@ -0,0 +1,62 @@ +pub const TYPE_NO_VOICE_ACTIVITY: i32 = 0; +pub const MAX_LPC_ORDER: i32 = 16; +pub const MIN_LPC_ORDER: i32 = 10; +pub const MAX_NB_SUBFR: i32 = 4; +pub const SHELL_CODEC_FRAME_LENGTH: i32 = 16; +pub const N_RATE_LEVELS: i32 = 10; +pub const SILK_MAX_PULSES: i32 = 16; +pub const TYPE_VOICED: i32 = 2; +pub const MAX_SHAPE_LPC_ORDER: i32 = 24; +pub const HARM_SHAPE_FIR_TAPS: i32 = 3; +pub const LTP_ORDER: i32 = 5; +pub const NSQ_LPC_BUF_LENGTH: i32 = MAX_LPC_ORDER; +pub const STEREO_INTERP_LEN_MS: i32 = 8; +pub const LA_SHAPE_MS: i32 = 5; +pub const STEREO_QUANT_SUB_STEPS: i32 = 5; +pub const STEREO_QUANT_TAB_SIZE: i32 = 16; +pub const MAX_DEL_DEC_STATES: i32 = 4; +pub const SUB_FRAME_LENGTH_MS: i32 = 5; +pub const CODE_INDEPENDENTLY: i32 = 0; +pub const CODE_CONDITIONALLY: i32 = 2; +pub const NLSF_QUANT_MAX_AMPLITUDE: i32 = 4; +pub const CODE_INDEPENDENTLY_NO_LTP_SCALING: i32 = 1; +pub const MAX_API_FS_KHZ: i32 = 48; +pub const DECODER_NUM_CHANNELS: i32 = 2; +pub const ENCODER_NUM_CHANNELS: i32 = 2; +pub const QUANT_LEVEL_ADJUST_Q10: i32 = 80; +pub const MIN_QGAIN_DB: i32 = 2; +pub const MIN_DELTA_GAIN_QUANT: i32 = -(4); +pub const N_LEVELS_QGAIN: i32 = 64; +pub const MAX_DELTA_GAIN_QUANT: i32 = 36; +pub const TRANSITION_NA: i32 = 2; +pub const TRANSITION_NB: i32 = 3; +pub const TRANSITION_INT_NUM: i32 = 5; +pub const OFFSET_UVL_Q10: i32 = 100; +pub const OFFSET_UVH_Q10: i32 = 240; +pub const OFFSET_VL_Q10: i32 = 32; +pub const OFFSET_VH_Q10: i32 = 100; +pub const NLSF_QUANT_DEL_DEC_STATES_LOG2: i32 = 2; +pub const NLSF_QUANT_DEL_DEC_STATES: i32 = (1) << NLSF_QUANT_DEL_DEC_STATES_LOG2; +pub const NLSF_QUANT_MAX_AMPLITUDE_EXT: i32 = 10; +pub const DECISION_DELAY: i32 = 40; +pub const MAX_FRAME_LENGTH_MS: i32 = SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR; +pub const TRANSITION_TIME_MS: i32 = 5120; +pub const TRANSITION_FRAMES: i32 = TRANSITION_TIME_MS / MAX_FRAME_LENGTH_MS; +pub const LSF_COS_TAB_SZ_FIX: i32 = 128; +pub const MAX_LPC_STABILIZE_ITERATIONS: i32 = 16; +pub const MAX_PREDICTION_POWER_GAIN: f32 = 1e4f32; +pub const CNG_BUF_MASK_MAX: i32 = 255; +pub const TYPE_UNVOICED: i32 = 1; +pub const NB_SPEECH_FRAMES_BEFORE_DTX: i32 = 10; +pub const MAX_CONSECUTIVE_DTX: i32 = 20; +pub const VAD_NO_ACTIVITY: i32 = 0; +pub const BWE_AFTER_LOSS_Q16: i32 = 63570; +pub const MAX_PREDICTION_POWER_GAIN_AFTER_RESET: f32 = 1e2f32; +pub const VAD_N_BANDS: i32 = 4; +pub const VAD_NEGATIVE_OFFSET_Q5: i32 = 128; +pub const VAD_NOISE_LEVEL_SMOOTH_COEF_Q16: i32 = 1024; +pub const VAD_INTERNAL_SUBFRAMES_LOG2: i32 = 2; +pub const VAD_INTERNAL_SUBFRAMES: i32 = (1) << VAD_INTERNAL_SUBFRAMES_LOG2; +pub const USE_HARM_SHAPING: i32 = 1; +pub const VAD_NO_DECISION: i32 = -1; +pub const DTX_ACTIVITY_THRESHOLD: f32 = 0.1f32; diff --git a/vendor/unsafe-libopus/src/silk/enc_API.rs b/vendor/unsafe-libopus/src/silk/enc_API.rs new file mode 100644 index 00000000..f76f82fd --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/enc_API.rs @@ -0,0 +1,873 @@ +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_EncControlStruct { + pub nChannelsAPI: i32, + pub nChannelsInternal: i32, + pub API_sampleRate: i32, + pub maxInternalSampleRate: i32, + pub minInternalSampleRate: i32, + pub desiredInternalSampleRate: i32, + pub payloadSize_ms: i32, + pub bitRate: i32, + pub packetLossPercentage: i32, + pub complexity: i32, + pub useInBandFEC: i32, + pub LBRR_coded: i32, + pub useDTX: i32, + pub useCBR: i32, + pub maxBits: i32, + pub toMono: i32, + pub opusCanSwitch: i32, + pub reducedDependency: i32, + pub internalSampleRate: i32, + pub allowBandwidthSwitch: i32, + pub inWBmodeWithoutVariableLP: i32, + pub stereoWidth_Q14: i32, + pub switchReady: i32, + pub signalType: i32, + pub offset: i32, +} +pub mod errors_h { + #[allow(unused)] + pub const SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES: i32 = -(101); + pub const SILK_NO_ERROR: i32 = 0; +} +use self::errors_h::SILK_NO_ERROR; +use crate::celt::entcode::ec_tell; +use crate::celt::entenc::{ec_enc, ec_enc_icdf, ec_enc_patch_initial_bits}; +use crate::externs::{memcpy, memset}; +use crate::silk::check_control_input::check_control_input; +use crate::silk::control_SNR::silk_control_SNR; +use crate::silk::control_codec::silk_control_encoder; +use crate::silk::define::{ + CODE_CONDITIONALLY, CODE_INDEPENDENTLY, CODE_INDEPENDENTLY_NO_LTP_SCALING, + ENCODER_NUM_CHANNELS, TYPE_NO_VOICE_ACTIVITY, +}; +use crate::silk::encode_indices::silk_encode_indices; +use crate::silk::encode_pulses::silk_encode_pulses; +use crate::silk::float::encode_frame_FLP::{silk_encode_do_VAD_FLP, silk_encode_frame_FLP}; +use crate::silk::float::structs_FLP::{silk_encoder, silk_encoder_state_FLP, silk_shape_state_FLP}; +use crate::silk::init_encoder::silk_init_encoder; +use crate::silk::resampler::silk_resampler; +use crate::silk::resampler::ResamplerState; +use crate::silk::stereo_LR_to_MS::silk_stereo_LR_to_MS; +use crate::silk::stereo_encode_pred::{silk_stereo_encode_mid_only, silk_stereo_encode_pred}; +use crate::silk::structs::{silk_LP_state, silk_nsq_state}; +use crate::silk::tables_other::{silk_LBRR_flags_iCDF_ptr, silk_Quantization_Offsets_Q10}; +use crate::silk::HP_variable_cutoff::silk_HP_variable_cutoff; + +pub unsafe fn silk_Get_Encoder_Size(encSizeBytes: *mut i32) -> i32 { + let ret: i32 = SILK_NO_ERROR; + *encSizeBytes = ::core::mem::size_of::() as u64 as i32; + return ret; +} +pub unsafe fn silk_InitEncoder( + encState: *mut core::ffi::c_void, + arch: i32, + encStatus: *mut silk_EncControlStruct, +) -> i32 { + let mut psEnc: *mut silk_encoder = 0 as *mut silk_encoder; + let mut n: i32 = 0; + let mut ret: i32 = SILK_NO_ERROR; + psEnc = encState as *mut silk_encoder; + memset( + psEnc as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + n = 0; + while n < ENCODER_NUM_CHANNELS { + ret += silk_init_encoder( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(n as isize), + arch, + ); + if ret != 0 { + panic!("libopus: assert(0) called"); + } + n += 1; + } + (*psEnc).nChannelsAPI = 1; + (*psEnc).nChannelsInternal = 1; + ret += silk_QueryEncoder(encState, encStatus); + if ret != 0 { + panic!("libopus: assert(0) called"); + } + return ret; +} +unsafe fn silk_QueryEncoder( + encState: *const core::ffi::c_void, + encStatus: *mut silk_EncControlStruct, +) -> i32 { + let ret: i32 = SILK_NO_ERROR; + let mut state_Fxx: *mut silk_encoder_state_FLP = 0 as *mut silk_encoder_state_FLP; + let psEnc: *mut silk_encoder = encState as *mut silk_encoder; + state_Fxx = ((*psEnc).state_Fxx).as_mut_ptr(); + (*encStatus).nChannelsAPI = (*psEnc).nChannelsAPI; + (*encStatus).nChannelsInternal = (*psEnc).nChannelsInternal; + (*encStatus).API_sampleRate = (*state_Fxx.offset(0 as isize)).sCmn.API_fs_Hz; + (*encStatus).maxInternalSampleRate = (*state_Fxx.offset(0 as isize)).sCmn.maxInternal_fs_Hz; + (*encStatus).minInternalSampleRate = (*state_Fxx.offset(0 as isize)).sCmn.minInternal_fs_Hz; + (*encStatus).desiredInternalSampleRate = + (*state_Fxx.offset(0 as isize)).sCmn.desiredInternal_fs_Hz; + (*encStatus).payloadSize_ms = (*state_Fxx.offset(0 as isize)).sCmn.PacketSize_ms; + (*encStatus).bitRate = (*state_Fxx.offset(0 as isize)).sCmn.TargetRate_bps; + (*encStatus).packetLossPercentage = (*state_Fxx.offset(0 as isize)).sCmn.PacketLoss_perc; + (*encStatus).complexity = (*state_Fxx.offset(0 as isize)).sCmn.Complexity; + (*encStatus).useInBandFEC = (*state_Fxx.offset(0 as isize)).sCmn.useInBandFEC; + (*encStatus).useDTX = (*state_Fxx.offset(0 as isize)).sCmn.useDTX; + (*encStatus).useCBR = (*state_Fxx.offset(0 as isize)).sCmn.useCBR; + (*encStatus).internalSampleRate = + (*state_Fxx.offset(0 as isize)).sCmn.fs_kHz as i16 as i32 * 1000; + (*encStatus).allowBandwidthSwitch = (*state_Fxx.offset(0 as isize)).sCmn.allow_bandwidth_switch; + (*encStatus).inWBmodeWithoutVariableLP = ((*state_Fxx.offset(0 as isize)).sCmn.fs_kHz == 16 + && (*state_Fxx.offset(0 as isize)).sCmn.sLP.mode == 0) + as i32; + return ret; +} +pub unsafe fn silk_Encode( + encState: *mut core::ffi::c_void, + encControl: *mut silk_EncControlStruct, + mut samplesIn: *const i16, + mut nSamplesIn: i32, + mut psRangeEnc: Option<&mut ec_enc>, + nBytesOut: *mut i32, + prefillFlag: i32, + activity: i32, +) -> i32 { + let mut n: i32 = 0; + let mut i: i32 = 0; + let mut nBits: i32 = 0; + let mut flags: i32 = 0; + let mut tmp_payloadSize_ms: i32 = 0; + let mut tmp_complexity: i32 = 0; + let mut ret: i32 = 0; + let mut nSamplesToBuffer: i32 = 0; + let mut nSamplesToBufferMax: i32 = 0; + let mut nBlocksOf10ms: i32 = 0; + let mut nSamplesFromInput: i32 = 0; + let mut nSamplesFromInputMax: i32 = 0; + let mut speech_act_thr_for_switch_Q8: i32 = 0; + let mut TargetRate_bps: i32 = 0; + let mut MStargetRates_bps: [i32; 2] = [0; 2]; + let mut channelRate_bps: i32 = 0; + let mut LBRR_symbol: i32 = 0; + let mut sum: i32 = 0; + let psEnc: *mut silk_encoder = encState as *mut silk_encoder; + let mut transition: i32 = 0; + let mut curr_block: i32 = 0; + let mut tot_blocks: i32 = 0; + if (*encControl).reducedDependency != 0 { + (*psEnc).state_Fxx[0 as usize].sCmn.first_frame_after_reset = 1; + (*psEnc).state_Fxx[1 as usize].sCmn.first_frame_after_reset = 1; + } + (*psEnc).state_Fxx[1 as usize].sCmn.nFramesEncoded = 0; + (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded = + (*psEnc).state_Fxx[1 as usize].sCmn.nFramesEncoded; + ret = check_control_input(encControl); + if ret != 0 { + // see comments in `[unsafe_libopus::silk::check_control_input]` + panic!("libopus: assert(0) called"); + // return ret; + } + (*encControl).switchReady = 0; + if (*encControl).nChannelsInternal > (*psEnc).nChannelsInternal { + ret += silk_init_encoder( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize), + (*psEnc).state_Fxx[0 as usize].sCmn.arch, + ); + memset( + ((*psEnc).sStereo.pred_prev_Q13).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 2]>() as u64, + ); + memset( + ((*psEnc).sStereo.sSide).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 2]>() as u64, + ); + (*psEnc).sStereo.mid_side_amp_Q0[0 as usize] = 0; + (*psEnc).sStereo.mid_side_amp_Q0[1 as usize] = 1; + (*psEnc).sStereo.mid_side_amp_Q0[2 as usize] = 0; + (*psEnc).sStereo.mid_side_amp_Q0[3 as usize] = 1; + (*psEnc).sStereo.width_prev_Q14 = 0; + (*psEnc).sStereo.smth_width_Q14 = ((1 * ((1) << 14)) as f64 + 0.5f64) as i32 as i16; + if (*psEnc).nChannelsAPI == 2 { + memcpy( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .resampler_state as *mut ResamplerState + as *mut core::ffi::c_void, + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .resampler_state as *mut ResamplerState + as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + memcpy( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .In_HP_State as *mut [i32; 2] as *mut core::ffi::c_void, + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .In_HP_State as *mut [i32; 2] as *const core::ffi::c_void, + ::core::mem::size_of::<[i32; 2]>() as u64, + ); + } + } + transition = ((*encControl).payloadSize_ms != (*psEnc).state_Fxx[0 as usize].sCmn.PacketSize_ms + || (*psEnc).nChannelsInternal != (*encControl).nChannelsInternal) as i32; + (*psEnc).nChannelsAPI = (*encControl).nChannelsAPI; + (*psEnc).nChannelsInternal = (*encControl).nChannelsInternal; + nBlocksOf10ms = 100 * nSamplesIn / (*encControl).API_sampleRate; + tot_blocks = if nBlocksOf10ms > 1 { + nBlocksOf10ms >> 1 + } else { + 1 + }; + curr_block = 0; + if prefillFlag != 0 { + let mut save_LP: silk_LP_state = silk_LP_state { + In_LP_State: [0; 2], + transition_frame_no: 0, + mode: 0, + saved_fs_kHz: 0, + }; + if nBlocksOf10ms != 1 { + // see comments in `[unsafe_libopus::silk::check_control_input]` + panic!("libopus: assert(0) called"); + // return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; + } + if prefillFlag == 2 { + save_LP = (*psEnc).state_Fxx[0 as usize].sCmn.sLP; + save_LP.saved_fs_kHz = (*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz; + } + n = 0; + while n < (*encControl).nChannelsInternal { + ret = silk_init_encoder( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(n as isize), + (*psEnc).state_Fxx[n as usize].sCmn.arch, + ); + if prefillFlag == 2 { + (*psEnc).state_Fxx[n as usize].sCmn.sLP = save_LP; + } + assert!(ret == 0); + n += 1; + } + tmp_payloadSize_ms = (*encControl).payloadSize_ms; + (*encControl).payloadSize_ms = 10; + tmp_complexity = (*encControl).complexity; + (*encControl).complexity = 0; + n = 0; + while n < (*encControl).nChannelsInternal { + (*psEnc).state_Fxx[n as usize] + .sCmn + .controlled_since_last_payload = 0; + (*psEnc).state_Fxx[n as usize].sCmn.prefillFlag = 1; + n += 1; + } + } else { + if nBlocksOf10ms * (*encControl).API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 { + // see comments in `[unsafe_libopus::silk::check_control_input]` + panic!("libopus: assert(0) called"); + // return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; + } + if 1000 * nSamplesIn > (*encControl).payloadSize_ms * (*encControl).API_sampleRate { + panic!("libopus: assert(0) called"); + // return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; + } + } + n = 0; + while n < (*encControl).nChannelsInternal { + let force_fs_kHz: i32 = if n == 1 { + (*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz + } else { + 0 + }; + ret = silk_control_encoder( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(n as isize), + encControl, + (*psEnc).allowBandwidthSwitch, + n, + force_fs_kHz, + ); + if ret != 0 { + return ret; + } + if (*psEnc).state_Fxx[n as usize].sCmn.first_frame_after_reset != 0 || transition != 0 { + i = 0; + while i < (*psEnc).state_Fxx[0 as usize].sCmn.nFramesPerPacket { + (*psEnc).state_Fxx[n as usize].sCmn.LBRR_flags[i as usize] = 0; + i += 1; + } + } + (*psEnc).state_Fxx[n as usize].sCmn.inDTX = (*psEnc).state_Fxx[n as usize].sCmn.useDTX; + n += 1; + } + assert!( + (*encControl).nChannelsInternal == 1 + || (*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz + == (*psEnc).state_Fxx[1 as usize].sCmn.fs_kHz + ); + nSamplesToBufferMax = 10 * nBlocksOf10ms * (*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz; + nSamplesFromInputMax = nSamplesToBufferMax * (*psEnc).state_Fxx[0 as usize].sCmn.API_fs_Hz + / ((*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz * 1000); + let vla = nSamplesFromInputMax as usize; + let mut buf: Vec = ::std::vec::from_elem(0, vla); + loop { + nSamplesToBuffer = (*psEnc).state_Fxx[0 as usize].sCmn.frame_length + - (*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx; + nSamplesToBuffer = if nSamplesToBuffer < nSamplesToBufferMax { + nSamplesToBuffer + } else { + nSamplesToBufferMax + }; + nSamplesFromInput = nSamplesToBuffer * (*psEnc).state_Fxx[0 as usize].sCmn.API_fs_Hz + / ((*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz * 1000); + if (*encControl).nChannelsAPI == 2 && (*encControl).nChannelsInternal == 2 { + let id: i32 = (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded; + n = 0; + while n < nSamplesFromInput { + *buf.as_mut_ptr().offset(n as isize) = *samplesIn.offset((2 * n) as isize); + n += 1; + } + /* Making sure to start both resamplers from the same state when switching from mono to stereo */ + if (*psEnc).nPrevChannelsInternal == 1 && id == 0 { + memcpy( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .resampler_state as *mut ResamplerState + as *mut core::ffi::c_void, + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .resampler_state as *mut ResamplerState + as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + } + ret += silk_resampler( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .resampler_state, + &mut (*psEnc).state_Fxx[0].sCmn.inputBuf + [((*psEnc).state_Fxx[0].sCmn.inputBufIx + 2) as usize..] + [..nSamplesToBuffer as usize], + &buf[..nSamplesFromInput as usize], + ); + (*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx += nSamplesToBuffer; + + nSamplesToBuffer = (*psEnc).state_Fxx[1 as usize].sCmn.frame_length + - (*psEnc).state_Fxx[1 as usize].sCmn.inputBufIx; + nSamplesToBuffer = if nSamplesToBuffer + < 10 * nBlocksOf10ms * (*psEnc).state_Fxx[1 as usize].sCmn.fs_kHz + { + nSamplesToBuffer + } else { + 10 * nBlocksOf10ms * (*psEnc).state_Fxx[1 as usize].sCmn.fs_kHz + }; + n = 0; + while n < nSamplesFromInput { + *buf.as_mut_ptr().offset(n as isize) = *samplesIn.offset((2 * n + 1) as isize); + n += 1; + } + ret += silk_resampler( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .resampler_state, + &mut (*psEnc).state_Fxx[1].sCmn.inputBuf + [((*psEnc).state_Fxx[1].sCmn.inputBufIx + 2) as usize..] + [..nSamplesToBuffer as usize], + &buf[..nSamplesFromInput as usize], + ); + + (*psEnc).state_Fxx[1].sCmn.inputBufIx += nSamplesToBuffer; + } else if (*encControl).nChannelsAPI == 2 && (*encControl).nChannelsInternal == 1 { + n = 0; + while n < nSamplesFromInput { + sum = *samplesIn.offset((2 * n) as isize) as i32 + + *samplesIn.offset((2 * n + 1) as isize) as i32; + *buf.as_mut_ptr().offset(n as isize) = (if 1 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 1 - 1) + 1 >> 1 + }) as i16; + n += 1; + } + ret += silk_resampler( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .resampler_state, + &mut (*psEnc).state_Fxx[0].sCmn.inputBuf + [((*psEnc).state_Fxx[0].sCmn.inputBufIx + 2) as usize..] + [..nSamplesToBuffer as usize], + &buf[..nSamplesFromInput as usize], + ); + if (*psEnc).nPrevChannelsInternal == 2 && (*psEnc).state_Fxx[0].sCmn.nFramesEncoded == 0 + { + ret += silk_resampler( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .resampler_state, + &mut (*psEnc).state_Fxx[1].sCmn.inputBuf + [((*psEnc).state_Fxx[1].sCmn.inputBufIx + 2) as usize..], + &buf[..nSamplesFromInput as usize], + ); + n = 0; + while n < (*psEnc).state_Fxx[0 as usize].sCmn.frame_length { + (*psEnc).state_Fxx[0 as usize].sCmn.inputBuf + [((*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx + n + 2) as usize] = + ((*psEnc).state_Fxx[0 as usize].sCmn.inputBuf + [((*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx + n + 2) as usize] + as i32 + + (*psEnc).state_Fxx[1 as usize].sCmn.inputBuf + [((*psEnc).state_Fxx[1 as usize].sCmn.inputBufIx + n + 2) as usize] + as i32 + >> 1) as i16; + n += 1; + } + } + (*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx += nSamplesToBuffer; + } else { + assert!((*encControl).nChannelsAPI == 1 && (*encControl).nChannelsInternal == 1); + memcpy( + buf.as_mut_ptr() as *mut core::ffi::c_void, + samplesIn as *const core::ffi::c_void, + (nSamplesFromInput as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + ret += silk_resampler( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .resampler_state, + &mut (*psEnc).state_Fxx[0].sCmn.inputBuf + [((*psEnc).state_Fxx[0].sCmn.inputBufIx + 2) as usize..] + [..nSamplesToBuffer as usize], + &buf[..nSamplesFromInput as usize], + ); + (*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx += nSamplesToBuffer; + } + samplesIn = samplesIn.offset((nSamplesFromInput * (*encControl).nChannelsAPI) as isize); + nSamplesIn -= nSamplesFromInput; + (*psEnc).allowBandwidthSwitch = 0; + if !((*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx + >= (*psEnc).state_Fxx[0 as usize].sCmn.frame_length) + { + break; + } + assert!( + (*psEnc).state_Fxx[0 as usize].sCmn.inputBufIx + == (*psEnc).state_Fxx[0 as usize].sCmn.frame_length + ); + assert!( + (*encControl).nChannelsInternal == 1 + || (*psEnc).state_Fxx[1 as usize].sCmn.inputBufIx + == (*psEnc).state_Fxx[1 as usize].sCmn.frame_length + ); + if (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded == 0 && prefillFlag == 0 { + // https://stackoverflow.com/questions/69615120/extracting-a-mutable-reference-from-an-option + let psRangeEnc = &mut **psRangeEnc.as_mut().unwrap(); + + let mut iCDF: [u8; 2] = [0, 0]; + iCDF[0] = (256 + - (256 + >> (((*psEnc).state_Fxx[0 as usize].sCmn.nFramesPerPacket + 1) + * (*encControl).nChannelsInternal))) as u8; + ec_enc_icdf(psRangeEnc, 0, &iCDF, 8); + n = 0; + while n < (*encControl).nChannelsInternal { + LBRR_symbol = 0; + i = 0; + while i < (*psEnc).state_Fxx[n as usize].sCmn.nFramesPerPacket { + LBRR_symbol |= (((*psEnc).state_Fxx[n as usize].sCmn.LBRR_flags[i as usize] + as u32) + << i) as i32; + i += 1; + } + (*psEnc).state_Fxx[n as usize].sCmn.LBRR_flag = + (if LBRR_symbol > 0 { 1 } else { 0 }) as i8; + if LBRR_symbol != 0 && (*psEnc).state_Fxx[n as usize].sCmn.nFramesPerPacket > 1 { + ec_enc_icdf( + psRangeEnc, + LBRR_symbol - 1, + silk_LBRR_flags_iCDF_ptr + [((*psEnc).state_Fxx[n as usize].sCmn.nFramesPerPacket - 2) as usize], + 8, + ); + } + n += 1; + } + i = 0; + while i < (*psEnc).state_Fxx[0 as usize].sCmn.nFramesPerPacket { + n = 0; + while n < (*encControl).nChannelsInternal { + if (*psEnc).state_Fxx[n as usize].sCmn.LBRR_flags[i as usize] != 0 { + let mut condCoding: i32 = 0; + if (*encControl).nChannelsInternal == 2 && n == 0 { + silk_stereo_encode_pred( + psRangeEnc, + ((*psEnc).sStereo.predIx[i as usize]).as_mut_ptr(), + ); + if (*psEnc).state_Fxx[1 as usize].sCmn.LBRR_flags[i as usize] == 0 { + silk_stereo_encode_mid_only( + psRangeEnc, + (*psEnc).sStereo.mid_only_flags[i as usize], + ); + } + } + if i > 0 + && (*psEnc).state_Fxx[n as usize].sCmn.LBRR_flags[(i - 1) as usize] != 0 + { + condCoding = CODE_CONDITIONALLY; + } else { + condCoding = CODE_INDEPENDENTLY; + } + silk_encode_indices( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(n as isize)).sCmn, + psRangeEnc, + i, + 1, + condCoding, + ); + silk_encode_pulses( + psRangeEnc, + (*psEnc).state_Fxx[n as usize].sCmn.indices_LBRR[i as usize].signalType + as i32, + (*psEnc).state_Fxx[n as usize].sCmn.indices_LBRR[i as usize] + .quantOffsetType as i32, + &mut (*psEnc).state_Fxx[n as usize].sCmn.pulses_LBRR[i as usize], + (*psEnc).state_Fxx[n as usize].sCmn.frame_length, + ); + } + n += 1; + } + i += 1; + } + n = 0; + while n < (*encControl).nChannelsInternal { + memset( + ((*psEnc).state_Fxx[n as usize].sCmn.LBRR_flags).as_mut_ptr() + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 3]>() as u64, + ); + n += 1; + } + (*psEnc).nBitsUsedLBRR = ec_tell(psRangeEnc); + } + silk_HP_variable_cutoff(((*psEnc).state_Fxx).as_mut_ptr()); + nBits = (*encControl).bitRate * (*encControl).payloadSize_ms / 1000; + if prefillFlag == 0 { + nBits -= (*psEnc).nBitsUsedLBRR; + } + nBits = nBits / (*psEnc).state_Fxx[0 as usize].sCmn.nFramesPerPacket; + if (*encControl).payloadSize_ms == 10 { + TargetRate_bps = nBits as i16 as i32 * 100; + } else { + TargetRate_bps = nBits as i16 as i32 * 50; + } + TargetRate_bps -= (*psEnc).nBitsExceeded * 1000 / 500; + if prefillFlag == 0 && (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded > 0 { + let bitsBalance: i32 = ec_tell(&mut **psRangeEnc.as_mut().unwrap()) + - (*psEnc).nBitsUsedLBRR + - nBits * (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded; + TargetRate_bps -= bitsBalance * 1000 / 500; + } + TargetRate_bps = if (*encControl).bitRate > 5000 { + if TargetRate_bps > (*encControl).bitRate { + (*encControl).bitRate + } else if TargetRate_bps < 5000 { + 5000 + } else { + TargetRate_bps + } + } else if TargetRate_bps > 5000 { + 5000 + } else if TargetRate_bps < (*encControl).bitRate { + (*encControl).bitRate + } else { + TargetRate_bps + }; + if (*encControl).nChannelsInternal == 2 { + silk_stereo_LR_to_MS( + &mut (*psEnc).sStereo, + &mut *((*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .inputBuf) + .as_mut_ptr() + .offset(2 as isize), + &mut *((*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .inputBuf) + .as_mut_ptr() + .offset(2 as isize), + ((*psEnc).sStereo.predIx + [(*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded as usize]) + .as_mut_ptr(), + &mut *((*psEnc).sStereo.mid_only_flags).as_mut_ptr().offset( + (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .nFramesEncoded as isize, + ), + MStargetRates_bps.as_mut_ptr(), + TargetRate_bps, + (*psEnc).state_Fxx[0 as usize].sCmn.speech_activity_Q8, + (*encControl).toMono, + (*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz, + (*psEnc).state_Fxx[0 as usize].sCmn.frame_length, + ); + if (*psEnc).sStereo.mid_only_flags + [(*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded as usize] as i32 + == 0 + { + if (*psEnc).prev_decode_only_middle == 1 { + memset( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)).sShape + as *mut silk_shape_state_FLP + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + memset( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .sNSQ as *mut silk_nsq_state + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + memset( + ((*psEnc).state_Fxx[1 as usize].sCmn.prev_NLSFq_Q15).as_mut_ptr() + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i16; 16]>() as u64, + ); + memset( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize)) + .sCmn + .sLP + .In_LP_State as *mut [i32; 2] + as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 2]>() as u64, + ); + (*psEnc).state_Fxx[1 as usize].sCmn.prevLag = 100; + (*psEnc).state_Fxx[1 as usize].sCmn.sNSQ.lagPrev = 100; + (*psEnc).state_Fxx[1 as usize].sShape.LastGainIndex = 10; + (*psEnc).state_Fxx[1 as usize].sCmn.prevSignalType = + TYPE_NO_VOICE_ACTIVITY as i8; + (*psEnc).state_Fxx[1 as usize].sCmn.sNSQ.prev_gain_Q16 = 65536; + (*psEnc).state_Fxx[1 as usize].sCmn.first_frame_after_reset = 1; + } + silk_encode_do_VAD_FLP( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(1 as isize), + activity, + ); + } else { + (*psEnc).state_Fxx[1 as usize].sCmn.VAD_flags + [(*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded as usize] = 0; + } + if prefillFlag == 0 { + let psRangeEnc = &mut **psRangeEnc.as_mut().unwrap(); + silk_stereo_encode_pred( + psRangeEnc, + ((*psEnc).sStereo.predIx + [(*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded as usize]) + .as_mut_ptr(), + ); + if (*psEnc).state_Fxx[1 as usize].sCmn.VAD_flags + [(*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded as usize] + as i32 + == 0 + { + silk_stereo_encode_mid_only( + psRangeEnc, + (*psEnc).sStereo.mid_only_flags + [(*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded as usize], + ); + } + } + } else { + memcpy( + ((*psEnc).state_Fxx[0 as usize].sCmn.inputBuf).as_mut_ptr() + as *mut core::ffi::c_void, + ((*psEnc).sStereo.sMid).as_mut_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*psEnc).sStereo.sMid).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .inputBuf) + .as_mut_ptr() + .offset( + (*((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize)) + .sCmn + .frame_length as isize, + ) as *mut i16 as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + } + silk_encode_do_VAD_FLP( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(0 as isize), + activity, + ); + n = 0; + while n < (*encControl).nChannelsInternal { + let mut maxBits: i32 = 0; + let mut useCBR: i32 = 0; + maxBits = (*encControl).maxBits; + if tot_blocks == 2 && curr_block == 0 { + maxBits = maxBits * 3 / 5; + } else if tot_blocks == 3 { + if curr_block == 0 { + maxBits = maxBits * 2 / 5; + } else if curr_block == 1 { + maxBits = maxBits * 3 / 4; + } + } + useCBR = ((*encControl).useCBR != 0 && curr_block == tot_blocks - 1) as i32; + if (*encControl).nChannelsInternal == 1 { + channelRate_bps = TargetRate_bps; + } else { + channelRate_bps = MStargetRates_bps[n as usize]; + if n == 0 && MStargetRates_bps[1 as usize] > 0 { + useCBR = 0; + maxBits -= (*encControl).maxBits / (tot_blocks * 2); + } + } + if channelRate_bps > 0 { + let mut condCoding_0: i32 = 0; + silk_control_SNR( + &mut (*((*psEnc).state_Fxx).as_mut_ptr().offset(n as isize)).sCmn, + channelRate_bps, + ); + if (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded - n <= 0 { + condCoding_0 = CODE_INDEPENDENTLY; + } else if n > 0 && (*psEnc).prev_decode_only_middle != 0 { + condCoding_0 = CODE_INDEPENDENTLY_NO_LTP_SCALING; + } else { + condCoding_0 = CODE_CONDITIONALLY; + } + let psRangeEnc = if let Some(psRangeEnc) = psRangeEnc.as_mut() { + Some(&mut **psRangeEnc) + } else { + None + }; + + ret = silk_encode_frame_FLP( + &mut *((*psEnc).state_Fxx).as_mut_ptr().offset(n as isize), + nBytesOut, + psRangeEnc, + condCoding_0, + maxBits, + useCBR, + ); + let _ = ret != 0; + } + (*psEnc).state_Fxx[n as usize] + .sCmn + .controlled_since_last_payload = 0; + (*psEnc).state_Fxx[n as usize].sCmn.inputBufIx = 0; + (*psEnc).state_Fxx[n as usize].sCmn.nFramesEncoded += 1; + n += 1; + } + (*psEnc).prev_decode_only_middle = (*psEnc).sStereo.mid_only_flags + [((*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded - 1) as usize] + as i32; + if *nBytesOut > 0 + && (*psEnc).state_Fxx[0 as usize].sCmn.nFramesEncoded + == (*psEnc).state_Fxx[0 as usize].sCmn.nFramesPerPacket + { + flags = 0; + n = 0; + while n < (*encControl).nChannelsInternal { + i = 0; + while i < (*psEnc).state_Fxx[n as usize].sCmn.nFramesPerPacket { + flags = ((flags as u32) << 1) as i32; + flags |= (*psEnc).state_Fxx[n as usize].sCmn.VAD_flags[i as usize] as i32; + i += 1; + } + flags = ((flags as u32) << 1) as i32; + flags |= (*psEnc).state_Fxx[n as usize].sCmn.LBRR_flag as i32; + n += 1; + } + if prefillFlag == 0 { + ec_enc_patch_initial_bits( + &mut **psRangeEnc.as_mut().unwrap(), + flags as u32, + (((*psEnc).state_Fxx[0 as usize].sCmn.nFramesPerPacket + 1) + * (*encControl).nChannelsInternal) as u32, + ); + } + if (*psEnc).state_Fxx[0 as usize].sCmn.inDTX != 0 + && ((*encControl).nChannelsInternal == 1 + || (*psEnc).state_Fxx[1 as usize].sCmn.inDTX != 0) + { + *nBytesOut = 0; + } + (*psEnc).nBitsExceeded += *nBytesOut * 8; + (*psEnc).nBitsExceeded -= (*encControl).bitRate * (*encControl).payloadSize_ms / 1000; + (*psEnc).nBitsExceeded = if 0 > 10000 { + if (*psEnc).nBitsExceeded > 0 { + 0 + } else if (*psEnc).nBitsExceeded < 10000 { + 10000 + } else { + (*psEnc).nBitsExceeded + } + } else if (*psEnc).nBitsExceeded > 10000 { + 10000 + } else if (*psEnc).nBitsExceeded < 0 { + 0 + } else { + (*psEnc).nBitsExceeded + }; + speech_act_thr_for_switch_Q8 = (((0.05f32 * ((1) << 8) as f32) as f64 + 0.5f64) as i32 + as i64 + + ((((1 as f32 - 0.05f32) / 5000 as f32 * ((1) << 16 + 8) as f32) as f64 + 0.5f64) + as i32 as i64 + * (*psEnc).timeSinceSwitchAllowed_ms as i16 as i64 + >> 16)) as i32; + if (*psEnc).state_Fxx[0 as usize].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 + { + (*psEnc).allowBandwidthSwitch = 1; + (*psEnc).timeSinceSwitchAllowed_ms = 0; + } else { + (*psEnc).allowBandwidthSwitch = 0; + (*psEnc).timeSinceSwitchAllowed_ms += (*encControl).payloadSize_ms; + } + } + if nSamplesIn == 0 { + break; + } + curr_block += 1; + } + (*psEnc).nPrevChannelsInternal = (*encControl).nChannelsInternal; + (*encControl).allowBandwidthSwitch = (*psEnc).allowBandwidthSwitch; + (*encControl).inWBmodeWithoutVariableLP = ((*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz == 16 + && (*psEnc).state_Fxx[0 as usize].sCmn.sLP.mode == 0) + as i32; + (*encControl).internalSampleRate = + (*psEnc).state_Fxx[0 as usize].sCmn.fs_kHz as i16 as i32 * 1000; + (*encControl).stereoWidth_Q14 = if (*encControl).toMono != 0 { + 0 + } else { + (*psEnc).sStereo.smth_width_Q14 as i32 + }; + if prefillFlag != 0 { + (*encControl).payloadSize_ms = tmp_payloadSize_ms; + (*encControl).complexity = tmp_complexity; + n = 0; + while n < (*encControl).nChannelsInternal { + (*psEnc).state_Fxx[n as usize] + .sCmn + .controlled_since_last_payload = 0; + (*psEnc).state_Fxx[n as usize].sCmn.prefillFlag = 0; + n += 1; + } + } + (*encControl).signalType = (*psEnc).state_Fxx[0 as usize].sCmn.indices.signalType as i32; + (*encControl).offset = silk_Quantization_Offsets_Q10 + [((*psEnc).state_Fxx[0 as usize].sCmn.indices.signalType as i32 >> 1) as usize] + [(*psEnc).state_Fxx[0 as usize].sCmn.indices.quantOffsetType as usize] + as i32; + return ret; +} diff --git a/vendor/unsafe-libopus/src/silk/encode_indices.rs b/vendor/unsafe-libopus/src/silk/encode_indices.rs new file mode 100644 index 00000000..4361682d --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/encode_indices.rs @@ -0,0 +1,198 @@ +use crate::celt::entenc::{ec_enc, ec_enc_icdf}; +use crate::silk::define::{ + CODE_CONDITIONALLY, CODE_INDEPENDENTLY, MAX_NB_SUBFR, NLSF_QUANT_MAX_AMPLITUDE, TYPE_VOICED, +}; +use crate::silk::structs::{silk_encoder_state, SideInfoIndices}; +use crate::silk::tables_LTP::{silk_LTP_gain_iCDF_ptrs, silk_LTP_per_index_iCDF}; +use crate::silk::tables_gain::{silk_delta_gain_iCDF, silk_gain_iCDF}; +use crate::silk::tables_other::{ + silk_LTPscale_iCDF, silk_NLSF_EXT_iCDF, silk_NLSF_interpolation_factor_iCDF, + silk_type_offset_VAD_iCDF, silk_type_offset_no_VAD_iCDF, silk_uniform4_iCDF, + silk_uniform8_iCDF, +}; +use crate::silk::tables_pitch_lag::{silk_pitch_delta_iCDF, silk_pitch_lag_iCDF}; +use crate::silk::NLSF_unpack::silk_NLSF_unpack; + +pub unsafe fn silk_encode_indices( + psEncC: *mut silk_encoder_state, + psRangeEnc: &mut ec_enc, + FrameIndex: i32, + encode_LBRR: i32, + condCoding: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut typeOffset: i32 = 0; + let mut encode_absolute_lagIndex: i32 = 0; + let mut delta_lagIndex: i32 = 0; + let mut ec_ix: [i16; 16] = [0; 16]; + let mut pred_Q8: [u8; 16] = [0; 16]; + let mut psIndices: *const SideInfoIndices = 0 as *const SideInfoIndices; + if encode_LBRR != 0 { + psIndices = &mut *((*psEncC).indices_LBRR) + .as_mut_ptr() + .offset(FrameIndex as isize) as *mut SideInfoIndices; + } else { + psIndices = &mut (*psEncC).indices; + } + typeOffset = 2 * (*psIndices).signalType as i32 + (*psIndices).quantOffsetType as i32; + assert!(typeOffset >= 0 && typeOffset < 6); + assert!(encode_LBRR == 0 || typeOffset >= 2); + if encode_LBRR != 0 || typeOffset >= 2 { + ec_enc_icdf(psRangeEnc, typeOffset - 2, &silk_type_offset_VAD_iCDF, 8); + } else { + ec_enc_icdf(psRangeEnc, typeOffset, &silk_type_offset_no_VAD_iCDF, 8); + } + if condCoding == CODE_CONDITIONALLY { + ec_enc_icdf( + psRangeEnc, + (*psIndices).GainsIndices[0 as usize] as i32, + &silk_delta_gain_iCDF, + 8, + ); + } else { + ec_enc_icdf( + psRangeEnc, + (*psIndices).GainsIndices[0 as usize] as i32 >> 3, + &silk_gain_iCDF[(*psIndices).signalType as usize], + 8, + ); + ec_enc_icdf( + psRangeEnc, + (*psIndices).GainsIndices[0 as usize] as i32 & 7, + &silk_uniform8_iCDF, + 8, + ); + } + i = 1; + while i < (*psEncC).nb_subfr { + ec_enc_icdf( + psRangeEnc, + (*psIndices).GainsIndices[i as usize] as i32, + &silk_delta_gain_iCDF, + 8, + ); + i += 1; + } + ec_enc_icdf( + psRangeEnc, + (*psIndices).NLSFIndices[0 as usize] as i32, + &(*(*psEncC).psNLSF_CB).CB1_iCDF[(((*psIndices).signalType as i32 >> 1) + * (*(*psEncC).psNLSF_CB).nVectors as i32) + as usize..], + 8, + ); + silk_NLSF_unpack( + &mut ec_ix, + &mut pred_Q8, + (*psEncC).psNLSF_CB, + (*psIndices).NLSFIndices[0 as usize] as i32, + ); + assert!((*(*psEncC).psNLSF_CB).order as i32 == (*psEncC).predictLPCOrder); + i = 0; + while i < (*(*psEncC).psNLSF_CB).order as i32 { + if (*psIndices).NLSFIndices[(i + 1) as usize] as i32 >= NLSF_QUANT_MAX_AMPLITUDE { + ec_enc_icdf( + psRangeEnc, + 2 * NLSF_QUANT_MAX_AMPLITUDE, + &(*(*psEncC).psNLSF_CB).ec_iCDF[*ec_ix.as_mut_ptr().offset(i as isize) as usize..], + 8, + ); + ec_enc_icdf( + psRangeEnc, + (*psIndices).NLSFIndices[(i + 1) as usize] as i32 - NLSF_QUANT_MAX_AMPLITUDE, + &silk_NLSF_EXT_iCDF, + 8, + ); + } else if (*psIndices).NLSFIndices[(i + 1) as usize] as i32 <= -NLSF_QUANT_MAX_AMPLITUDE { + ec_enc_icdf( + psRangeEnc, + 0, + &(*(*psEncC).psNLSF_CB).ec_iCDF[*ec_ix.as_mut_ptr().offset(i as isize) as usize..], + 8, + ); + ec_enc_icdf( + psRangeEnc, + -((*psIndices).NLSFIndices[(i + 1) as usize] as i32) - NLSF_QUANT_MAX_AMPLITUDE, + &silk_NLSF_EXT_iCDF, + 8, + ); + } else { + ec_enc_icdf( + psRangeEnc, + (*psIndices).NLSFIndices[(i + 1) as usize] as i32 + NLSF_QUANT_MAX_AMPLITUDE, + &(*(*psEncC).psNLSF_CB).ec_iCDF[*ec_ix.as_mut_ptr().offset(i as isize) as usize..], + 8, + ); + } + i += 1; + } + if (*psEncC).nb_subfr == MAX_NB_SUBFR { + ec_enc_icdf( + psRangeEnc, + (*psIndices).NLSFInterpCoef_Q2 as i32, + &silk_NLSF_interpolation_factor_iCDF, + 8, + ); + } + if (*psIndices).signalType as i32 == TYPE_VOICED { + encode_absolute_lagIndex = 1; + if condCoding == CODE_CONDITIONALLY && (*psEncC).ec_prevSignalType == TYPE_VOICED { + delta_lagIndex = (*psIndices).lagIndex as i32 - (*psEncC).ec_prevLagIndex as i32; + if delta_lagIndex < -(8) || delta_lagIndex > 11 { + delta_lagIndex = 0; + } else { + delta_lagIndex = delta_lagIndex + 9; + encode_absolute_lagIndex = 0; + } + ec_enc_icdf(psRangeEnc, delta_lagIndex, &silk_pitch_delta_iCDF, 8); + } + if encode_absolute_lagIndex != 0 { + let mut pitch_high_bits: i32 = 0; + let mut pitch_low_bits: i32 = 0; + pitch_high_bits = (*psIndices).lagIndex as i32 / ((*psEncC).fs_kHz >> 1); + pitch_low_bits = (*psIndices).lagIndex as i32 + - pitch_high_bits as i16 as i32 * ((*psEncC).fs_kHz >> 1) as i16 as i32; + ec_enc_icdf(psRangeEnc, pitch_high_bits, &silk_pitch_lag_iCDF, 8); + ec_enc_icdf( + psRangeEnc, + pitch_low_bits, + (*psEncC).pitch_lag_low_bits_iCDF, + 8, + ); + } + (*psEncC).ec_prevLagIndex = (*psIndices).lagIndex; + ec_enc_icdf( + psRangeEnc, + (*psIndices).contourIndex as i32, + (*psEncC).pitch_contour_iCDF, + 8, + ); + ec_enc_icdf( + psRangeEnc, + (*psIndices).PERIndex as i32, + &silk_LTP_per_index_iCDF, + 8, + ); + k = 0; + while k < (*psEncC).nb_subfr { + ec_enc_icdf( + psRangeEnc, + (*psIndices).LTPIndex[k as usize] as i32, + silk_LTP_gain_iCDF_ptrs[(*psIndices).PERIndex as usize], + 8, + ); + k += 1; + } + if condCoding == CODE_INDEPENDENTLY { + ec_enc_icdf( + psRangeEnc, + (*psIndices).LTP_scaleIndex as i32, + &silk_LTPscale_iCDF, + 8, + ); + } + } + (*psEncC).ec_prevSignalType = (*psIndices).signalType as i32; + ec_enc_icdf(psRangeEnc, (*psIndices).Seed as i32, &silk_uniform4_iCDF, 8); +} diff --git a/vendor/unsafe-libopus/src/silk/encode_pulses.rs b/vendor/unsafe-libopus/src/silk/encode_pulses.rs new file mode 100644 index 00000000..95395d9d --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/encode_pulses.rs @@ -0,0 +1,232 @@ +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; +} +pub use self::typedef_h::silk_int32_MAX; +use crate::celt::entenc::{ec_enc, ec_enc_icdf}; +use crate::silk::code_signs::silk_encode_signs; +use crate::silk::define::{N_RATE_LEVELS, SHELL_CODEC_FRAME_LENGTH, SILK_MAX_PULSES}; +use crate::silk::shell_coder::silk_shell_encoder; +use crate::silk::tables_other::silk_lsb_iCDF; +use crate::silk::tables_pulses_per_block::{ + silk_max_pulses_table, silk_pulses_per_block_BITS_Q5, silk_pulses_per_block_iCDF, + silk_rate_levels_BITS_Q5, silk_rate_levels_iCDF, +}; + +#[inline] +fn combine_and_check( + pulses_comb: &mut [i32], + pulses_in: Option<&[i32]>, + max_pulses: i32, + len: i32, +) -> i32 { + for k in 0..len as usize { + let pulses_in = if let Some(pulses_in) = pulses_in { + pulses_in + } else { + &*pulses_comb + }; + + let sum = pulses_in[2 * k] + pulses_in[2 * k + 1]; + if sum > max_pulses { + return 1; + } + pulses_comb[k] = sum; + } + + 0 +} + +/// Encode quantization indices of excitation +pub fn silk_encode_pulses( + psRangeEnc: &mut ec_enc, + signalType: i32, + quantOffsetType: i32, + pulses_buffer: &mut [i8], + frame_length: i32, +) { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut j: i32 = 0; + let mut iter: i32 = 0; + let mut bit: i32 = 0; + let mut nLS: i32 = 0; + let mut scale_down: i32 = 0; + let mut RateLevelIndex: i32 = 0; + let mut abs_q: i32 = 0; + let mut minSumBits_Q5: i32 = 0; + let mut sumBits_Q5: i32 = 0; + let mut pulses_comb: [i32; 8] = [0; 8]; + + /****************************/ + /* Prepare for shell coding */ + /****************************/ + /* Calculate number of shell blocks */ + iter = frame_length >> 4; + // special case for 10 ms @ 12 kHz: the frame length is not a multiple of SHELL_CODEC_FRAME_LENGTH + // we expand the frame length to the next multiple of SHELL_CODEC_FRAME_LENGTH, filling the extra space with zeros + if iter * SHELL_CODEC_FRAME_LENGTH < frame_length { + assert_eq!(frame_length, 12 * 10); /* Make sure only happens for 10 ms @ 12 kHz */ + iter += 1; + + // zero out the unused part of pulses_buffer + pulses_buffer[frame_length as usize..].fill(0); + } + let pulses_frame = &mut pulses_buffer[..(iter * SHELL_CODEC_FRAME_LENGTH) as usize]; + + /* Take the absolute value of the pulses */ + let mut abs_pulses = pulses_frame + .iter() + .copied() + .map(|v| v.abs() as i32) + .collect::>(); + + /* Calc sum pulses per shell code frame */ + let vla_0 = iter as usize; + let mut sum_pulses: Vec = ::std::vec::from_elem(0, vla_0); + let vla_1 = iter as usize; + let mut nRshifts: Vec = ::std::vec::from_elem(0, vla_1); + let mut abs_pulses_ptr = abs_pulses.as_mut_slice(); + i = 0; + while i < iter { + nRshifts[i as usize] = 0; + loop { + scale_down = combine_and_check( + &mut pulses_comb, + Some(abs_pulses_ptr), + silk_max_pulses_table[0] as i32, + 8, + ); + scale_down += + combine_and_check(&mut pulses_comb, None, silk_max_pulses_table[1] as i32, 4); + scale_down += + combine_and_check(&mut pulses_comb, None, silk_max_pulses_table[2] as i32, 2); + scale_down += combine_and_check( + &mut sum_pulses[i as usize..][..1], + Some(&pulses_comb), + silk_max_pulses_table[3] as i32, + 1, + ); + if !(scale_down != 0) { + break; + } + nRshifts[i as usize] += 1; + k = 0; + while k < SHELL_CODEC_FRAME_LENGTH { + abs_pulses_ptr[k as usize] >>= 1; + k += 1; + } + } + abs_pulses_ptr = &mut abs_pulses_ptr[SHELL_CODEC_FRAME_LENGTH as usize..]; + + i += 1; + } + + /**************/ + /* Rate level */ + /**************/ + /* find rate level that leads to fewest bits for coding of pulses per block info */ + minSumBits_Q5 = silk_int32_MAX; + k = 0; + while k < N_RATE_LEVELS - 1 { + let nBits_ptr = &silk_pulses_per_block_BITS_Q5[k as usize]; + sumBits_Q5 = silk_rate_levels_BITS_Q5[(signalType >> 1) as usize][k as usize] as i32; + i = 0; + while i < iter { + if nRshifts[i as usize] > 0 { + sumBits_Q5 += nBits_ptr[(SILK_MAX_PULSES + 1) as usize] as i32; + } else { + sumBits_Q5 += nBits_ptr[sum_pulses[i as usize] as usize] as i32; + } + i += 1; + } + if sumBits_Q5 < minSumBits_Q5 { + minSumBits_Q5 = sumBits_Q5; + RateLevelIndex = k; + } + k += 1; + } + ec_enc_icdf( + psRangeEnc, + RateLevelIndex, + &silk_rate_levels_iCDF[(signalType >> 1) as usize], + 8, + ); + + /***************************************************/ + /* Sum-Weighted-Pulses Encoding */ + /***************************************************/ + let cdf_ptr = &silk_pulses_per_block_iCDF[RateLevelIndex as usize]; + for i in 0..iter as usize { + if nRshifts[i] == 0 { + ec_enc_icdf(psRangeEnc, sum_pulses[i], cdf_ptr, 8); + } else { + ec_enc_icdf(psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8); + k = 0; + while k < nRshifts[i] - 1 { + ec_enc_icdf( + psRangeEnc, + SILK_MAX_PULSES + 1, + &silk_pulses_per_block_iCDF[(N_RATE_LEVELS - 1) as usize], + 8, + ); + k += 1; + } + ec_enc_icdf( + psRangeEnc, + sum_pulses[i], + &silk_pulses_per_block_iCDF[(N_RATE_LEVELS - 1) as usize], + 8, + ); + } + } + + /******************/ + /* Shell Encoding */ + /******************/ + for (i, chunk) in abs_pulses + .chunks_exact(SHELL_CODEC_FRAME_LENGTH as usize) + .enumerate() + { + if sum_pulses[i] > 0 { + silk_shell_encoder(psRangeEnc, chunk); + } + } + + /****************/ + /* LSB Encoding */ + /****************/ + i = 0; + while i < iter { + if nRshifts[i as usize] > 0 { + let pulses_ptr = &mut pulses_frame[(i * SHELL_CODEC_FRAME_LENGTH) as usize..] + [..SHELL_CODEC_FRAME_LENGTH as usize]; + nLS = nRshifts[i as usize] - 1; + k = 0; + while k < SHELL_CODEC_FRAME_LENGTH { + abs_q = pulses_ptr[k as usize].abs() as i32; + j = nLS; + while j > 0 { + bit = abs_q >> j & 1; + ec_enc_icdf(psRangeEnc, bit, &silk_lsb_iCDF, 8); + j -= 1; + } + bit = abs_q & 1; + ec_enc_icdf(psRangeEnc, bit, &silk_lsb_iCDF, 8); + k += 1; + } + } + i += 1; + } + + /****************/ + /* Encode signs */ + /****************/ + silk_encode_signs( + psRangeEnc, + pulses_frame, + frame_length, + signalType, + quantOffsetType, + &sum_pulses, + ); +} diff --git a/vendor/unsafe-libopus/src/silk/float/LPC_analysis_filter_FLP.rs b/vendor/unsafe-libopus/src/silk/float/LPC_analysis_filter_FLP.rs new file mode 100644 index 00000000..58cbd5cf --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/LPC_analysis_filter_FLP.rs @@ -0,0 +1,172 @@ +use crate::externs::memset; +#[inline] +unsafe fn silk_LPC_analysis_filter16_FLP( + r_LPC: *mut f32, + PredCoef: *const f32, + s: *const f32, + length: i32, +) { + let mut ix: i32 = 0; + let mut LPC_pred: f32 = 0.; + let mut s_ptr: *const f32 = 0 as *const f32; + ix = 16; + while ix < length { + s_ptr = &*s.offset((ix - 1) as isize) as *const f32; + LPC_pred = *s_ptr.offset(0 as isize) * *PredCoef.offset(0 as isize) + + *s_ptr.offset(-1 as isize) * *PredCoef.offset(1 as isize) + + *s_ptr.offset(-(2) as isize) * *PredCoef.offset(2 as isize) + + *s_ptr.offset(-(3) as isize) * *PredCoef.offset(3 as isize) + + *s_ptr.offset(-(4) as isize) * *PredCoef.offset(4 as isize) + + *s_ptr.offset(-(5) as isize) * *PredCoef.offset(5 as isize) + + *s_ptr.offset(-(6) as isize) * *PredCoef.offset(6 as isize) + + *s_ptr.offset(-(7) as isize) * *PredCoef.offset(7 as isize) + + *s_ptr.offset(-(8) as isize) * *PredCoef.offset(8 as isize) + + *s_ptr.offset(-(9) as isize) * *PredCoef.offset(9 as isize) + + *s_ptr.offset(-(10) as isize) * *PredCoef.offset(10 as isize) + + *s_ptr.offset(-(11) as isize) * *PredCoef.offset(11 as isize) + + *s_ptr.offset(-(12) as isize) * *PredCoef.offset(12 as isize) + + *s_ptr.offset(-(13) as isize) * *PredCoef.offset(13 as isize) + + *s_ptr.offset(-(14) as isize) * *PredCoef.offset(14 as isize) + + *s_ptr.offset(-(15) as isize) * *PredCoef.offset(15 as isize); + *r_LPC.offset(ix as isize) = *s_ptr.offset(1 as isize) - LPC_pred; + ix += 1; + } +} +#[inline] +unsafe fn silk_LPC_analysis_filter12_FLP( + r_LPC: *mut f32, + PredCoef: *const f32, + s: *const f32, + length: i32, +) { + let mut ix: i32 = 0; + let mut LPC_pred: f32 = 0.; + let mut s_ptr: *const f32 = 0 as *const f32; + ix = 12; + while ix < length { + s_ptr = &*s.offset((ix - 1) as isize) as *const f32; + LPC_pred = *s_ptr.offset(0 as isize) * *PredCoef.offset(0 as isize) + + *s_ptr.offset(-1 as isize) * *PredCoef.offset(1 as isize) + + *s_ptr.offset(-(2) as isize) * *PredCoef.offset(2 as isize) + + *s_ptr.offset(-(3) as isize) * *PredCoef.offset(3 as isize) + + *s_ptr.offset(-(4) as isize) * *PredCoef.offset(4 as isize) + + *s_ptr.offset(-(5) as isize) * *PredCoef.offset(5 as isize) + + *s_ptr.offset(-(6) as isize) * *PredCoef.offset(6 as isize) + + *s_ptr.offset(-(7) as isize) * *PredCoef.offset(7 as isize) + + *s_ptr.offset(-(8) as isize) * *PredCoef.offset(8 as isize) + + *s_ptr.offset(-(9) as isize) * *PredCoef.offset(9 as isize) + + *s_ptr.offset(-(10) as isize) * *PredCoef.offset(10 as isize) + + *s_ptr.offset(-(11) as isize) * *PredCoef.offset(11 as isize); + *r_LPC.offset(ix as isize) = *s_ptr.offset(1 as isize) - LPC_pred; + ix += 1; + } +} +#[inline] +unsafe fn silk_LPC_analysis_filter10_FLP( + r_LPC: *mut f32, + PredCoef: *const f32, + s: *const f32, + length: i32, +) { + let mut ix: i32 = 0; + let mut LPC_pred: f32 = 0.; + let mut s_ptr: *const f32 = 0 as *const f32; + ix = 10; + while ix < length { + s_ptr = &*s.offset((ix - 1) as isize) as *const f32; + LPC_pred = *s_ptr.offset(0 as isize) * *PredCoef.offset(0 as isize) + + *s_ptr.offset(-1 as isize) * *PredCoef.offset(1 as isize) + + *s_ptr.offset(-(2) as isize) * *PredCoef.offset(2 as isize) + + *s_ptr.offset(-(3) as isize) * *PredCoef.offset(3 as isize) + + *s_ptr.offset(-(4) as isize) * *PredCoef.offset(4 as isize) + + *s_ptr.offset(-(5) as isize) * *PredCoef.offset(5 as isize) + + *s_ptr.offset(-(6) as isize) * *PredCoef.offset(6 as isize) + + *s_ptr.offset(-(7) as isize) * *PredCoef.offset(7 as isize) + + *s_ptr.offset(-(8) as isize) * *PredCoef.offset(8 as isize) + + *s_ptr.offset(-(9) as isize) * *PredCoef.offset(9 as isize); + *r_LPC.offset(ix as isize) = *s_ptr.offset(1 as isize) - LPC_pred; + ix += 1; + } +} +#[inline] +unsafe fn silk_LPC_analysis_filter8_FLP( + r_LPC: *mut f32, + PredCoef: *const f32, + s: *const f32, + length: i32, +) { + let mut ix: i32 = 0; + let mut LPC_pred: f32 = 0.; + let mut s_ptr: *const f32 = 0 as *const f32; + ix = 8; + while ix < length { + s_ptr = &*s.offset((ix - 1) as isize) as *const f32; + LPC_pred = *s_ptr.offset(0 as isize) * *PredCoef.offset(0 as isize) + + *s_ptr.offset(-1 as isize) * *PredCoef.offset(1 as isize) + + *s_ptr.offset(-(2) as isize) * *PredCoef.offset(2 as isize) + + *s_ptr.offset(-(3) as isize) * *PredCoef.offset(3 as isize) + + *s_ptr.offset(-(4) as isize) * *PredCoef.offset(4 as isize) + + *s_ptr.offset(-(5) as isize) * *PredCoef.offset(5 as isize) + + *s_ptr.offset(-(6) as isize) * *PredCoef.offset(6 as isize) + + *s_ptr.offset(-(7) as isize) * *PredCoef.offset(7 as isize); + *r_LPC.offset(ix as isize) = *s_ptr.offset(1 as isize) - LPC_pred; + ix += 1; + } +} +#[inline] +unsafe fn silk_LPC_analysis_filter6_FLP( + r_LPC: *mut f32, + PredCoef: *const f32, + s: *const f32, + length: i32, +) { + let mut ix: i32 = 0; + let mut LPC_pred: f32 = 0.; + let mut s_ptr: *const f32 = 0 as *const f32; + ix = 6; + while ix < length { + s_ptr = &*s.offset((ix - 1) as isize) as *const f32; + LPC_pred = *s_ptr.offset(0 as isize) * *PredCoef.offset(0 as isize) + + *s_ptr.offset(-1 as isize) * *PredCoef.offset(1 as isize) + + *s_ptr.offset(-(2) as isize) * *PredCoef.offset(2 as isize) + + *s_ptr.offset(-(3) as isize) * *PredCoef.offset(3 as isize) + + *s_ptr.offset(-(4) as isize) * *PredCoef.offset(4 as isize) + + *s_ptr.offset(-(5) as isize) * *PredCoef.offset(5 as isize); + *r_LPC.offset(ix as isize) = *s_ptr.offset(1 as isize) - LPC_pred; + ix += 1; + } +} +pub unsafe fn silk_LPC_analysis_filter_FLP( + r_LPC: *mut f32, + PredCoef: *const f32, + s: *const f32, + length: i32, + Order: i32, +) { + assert!(Order <= length); + match Order { + 6 => { + silk_LPC_analysis_filter6_FLP(r_LPC, PredCoef, s, length); + } + 8 => { + silk_LPC_analysis_filter8_FLP(r_LPC, PredCoef, s, length); + } + 10 => { + silk_LPC_analysis_filter10_FLP(r_LPC, PredCoef, s, length); + } + 12 => { + silk_LPC_analysis_filter12_FLP(r_LPC, PredCoef, s, length); + } + 16 => { + silk_LPC_analysis_filter16_FLP(r_LPC, PredCoef, s, length); + } + _ => { + panic!("libopus: assert(0) called"); + } + } + memset( + r_LPC as *mut core::ffi::c_void, + 0, + (Order as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); +} diff --git a/vendor/unsafe-libopus/src/silk/float/LTP_analysis_filter_FLP.rs b/vendor/unsafe-libopus/src/silk/float/LTP_analysis_filter_FLP.rs new file mode 100644 index 00000000..bbb9b7ba --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/LTP_analysis_filter_FLP.rs @@ -0,0 +1,48 @@ +use crate::silk::define::LTP_ORDER; +pub unsafe fn silk_LTP_analysis_filter_FLP( + LTP_res: *mut f32, + x: *const f32, + B: *const f32, + pitchL: *const i32, + invGains: *const f32, + subfr_length: i32, + nb_subfr: i32, + pre_length: i32, +) { + let mut x_ptr: *const f32 = 0 as *const f32; + let mut x_lag_ptr: *const f32 = 0 as *const f32; + let mut Btmp: [f32; 5] = [0.; 5]; + let mut LTP_res_ptr: *mut f32 = 0 as *mut f32; + let mut inv_gain: f32 = 0.; + let mut k: i32 = 0; + let mut i: i32 = 0; + let mut j: i32 = 0; + x_ptr = x; + LTP_res_ptr = LTP_res; + k = 0; + while k < nb_subfr { + x_lag_ptr = x_ptr.offset(-(*pitchL.offset(k as isize) as isize)); + inv_gain = *invGains.offset(k as isize); + i = 0; + while i < LTP_ORDER { + Btmp[i as usize] = *B.offset((k * LTP_ORDER + i) as isize); + i += 1; + } + i = 0; + while i < subfr_length + pre_length { + *LTP_res_ptr.offset(i as isize) = *x_ptr.offset(i as isize); + j = 0; + while j < LTP_ORDER { + *LTP_res_ptr.offset(i as isize) -= + Btmp[j as usize] * *x_lag_ptr.offset((LTP_ORDER / 2 - j) as isize); + j += 1; + } + *LTP_res_ptr.offset(i as isize) *= inv_gain; + x_lag_ptr = x_lag_ptr.offset(1); + i += 1; + } + LTP_res_ptr = LTP_res_ptr.offset((subfr_length + pre_length) as isize); + x_ptr = x_ptr.offset(subfr_length as isize); + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/LTP_scale_ctrl_FLP.rs b/vendor/unsafe-libopus/src/silk/float/LTP_scale_ctrl_FLP.rs new file mode 100644 index 00000000..fbc66e12 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/LTP_scale_ctrl_FLP.rs @@ -0,0 +1,33 @@ +use crate::silk::define::CODE_INDEPENDENTLY; +use crate::silk::float::structs_FLP::{silk_encoder_control_FLP, silk_encoder_state_FLP}; +use crate::silk::tables_other::silk_LTPScales_table_Q14; + +pub unsafe fn silk_LTP_scale_ctrl_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + condCoding: i32, +) { + let mut round_loss: i32 = 0; + if condCoding == CODE_INDEPENDENTLY { + round_loss = (*psEnc).sCmn.PacketLoss_perc + (*psEnc).sCmn.nFramesPerPacket; + (*psEnc).sCmn.indices.LTP_scaleIndex = (if 0.0f32 > 2.0f32 { + if round_loss as f32 * (*psEncCtrl).LTPredCodGain * 0.1f32 > 0.0f32 { + 0.0f32 + } else if round_loss as f32 * (*psEncCtrl).LTPredCodGain * 0.1f32 < 2.0f32 { + 2.0f32 + } else { + round_loss as f32 * (*psEncCtrl).LTPredCodGain * 0.1f32 + } + } else if round_loss as f32 * (*psEncCtrl).LTPredCodGain * 0.1f32 > 2.0f32 { + 2.0f32 + } else if round_loss as f32 * (*psEncCtrl).LTPredCodGain * 0.1f32 < 0.0f32 { + 0.0f32 + } else { + round_loss as f32 * (*psEncCtrl).LTPredCodGain * 0.1f32 + }) as i8; + } else { + (*psEnc).sCmn.indices.LTP_scaleIndex = 0; + } + (*psEncCtrl).LTP_scale = + silk_LTPScales_table_Q14[(*psEnc).sCmn.indices.LTP_scaleIndex as usize] as f32 / 16384.0f32; +} diff --git a/vendor/unsafe-libopus/src/silk/float/apply_sine_window_FLP.rs b/vendor/unsafe-libopus/src/silk/float/apply_sine_window_FLP.rs new file mode 100644 index 00000000..8bf3e7ed --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/apply_sine_window_FLP.rs @@ -0,0 +1,33 @@ +pub unsafe fn silk_apply_sine_window_FLP( + px_win: *mut f32, + px: *const f32, + win_type: i32, + length: i32, +) { + let mut k: i32 = 0; + let mut freq: f32 = 0.; + let mut c: f32 = 0.; + let mut S0: f32 = 0.; + let mut S1: f32 = 0.; + assert!(win_type == 1 || win_type == 2); + assert!(length & 3 == 0); + freq = std::f32::consts::PI / (length + 1) as f32; + c = 2.0f32 - freq * freq; + if win_type < 2 { + S0 = 0.0f32; + S1 = freq; + } else { + S0 = 1.0f32; + S1 = 0.5f32 * c; + } + k = 0; + while k < length { + *px_win.offset((k + 0) as isize) = *px.offset((k + 0) as isize) * 0.5f32 * (S0 + S1); + *px_win.offset((k + 1) as isize) = *px.offset((k + 1) as isize) * S1; + S0 = c * S1 - S0; + *px_win.offset((k + 2) as isize) = *px.offset((k + 2) as isize) * 0.5f32 * (S1 + S0); + *px_win.offset((k + 3) as isize) = *px.offset((k + 3) as isize) * S0; + S1 = c * S0 - S1; + k += 4; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/autocorrelation_FLP.rs b/vendor/unsafe-libopus/src/silk/float/autocorrelation_FLP.rs new file mode 100644 index 00000000..a452bfbc --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/autocorrelation_FLP.rs @@ -0,0 +1,20 @@ +use crate::silk::float::inner_product_FLP::silk_inner_product_FLP; + +pub unsafe fn silk_autocorrelation_FLP( + results: *mut f32, + inputData: *const f32, + inputDataSize: i32, + mut correlationCount: i32, +) { + let mut i: i32 = 0; + if correlationCount > inputDataSize { + correlationCount = inputDataSize; + } + i = 0; + while i < correlationCount { + *results.offset(i as isize) = + silk_inner_product_FLP(inputData, inputData.offset(i as isize), inputDataSize - i) + as f32; + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/burg_modified_FLP.rs b/vendor/unsafe-libopus/src/silk/float/burg_modified_FLP.rs new file mode 100644 index 00000000..f95ffed3 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/burg_modified_FLP.rs @@ -0,0 +1,177 @@ +pub mod tuning_parameters_h { + pub const FIND_LPC_COND_FAC: f32 = 1e-5f32; +} +pub use self::tuning_parameters_h::FIND_LPC_COND_FAC; +use crate::externs::{memcpy, memset}; +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::inner_product_FLP::silk_inner_product_FLP; + +pub unsafe fn silk_burg_modified_FLP( + A: *mut f32, + x: *const f32, + minInvGain: f32, + subfr_length: i32, + nb_subfr: i32, + D: i32, +) -> f32 { + let mut k: i32 = 0; + let mut n: i32 = 0; + let mut s: i32 = 0; + let mut reached_max_gain: i32 = 0; + let mut C0: f64 = 0.; + let mut invGain: f64 = 0.; + let mut num: f64 = 0.; + let mut nrg_f: f64 = 0.; + let mut nrg_b: f64 = 0.; + let mut rc: f64 = 0.; + let mut Atmp: f64 = 0.; + let mut tmp1: f64 = 0.; + let mut tmp2: f64 = 0.; + let mut x_ptr: *const f32 = 0 as *const f32; + let mut C_first_row: [f64; 24] = [0.; 24]; + let mut C_last_row: [f64; 24] = [0.; 24]; + let mut CAf: [f64; 25] = [0.; 25]; + let mut CAb: [f64; 25] = [0.; 25]; + let mut Af: [f64; 24] = [0.; 24]; + assert!(subfr_length * nb_subfr <= 384); + C0 = silk_energy_FLP(x, nb_subfr * subfr_length); + memset( + C_first_row.as_mut_ptr() as *mut core::ffi::c_void, + 0, + 24_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + s = 0; + while s < nb_subfr { + x_ptr = x.offset((s * subfr_length) as isize); + n = 1; + while n < D + 1 { + C_first_row[(n - 1) as usize] += + silk_inner_product_FLP(x_ptr, x_ptr.offset(n as isize), subfr_length - n); + n += 1; + } + s += 1; + } + memcpy( + C_last_row.as_mut_ptr() as *mut core::ffi::c_void, + C_first_row.as_mut_ptr() as *const core::ffi::c_void, + 24_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + CAf[0 as usize] = C0 + FIND_LPC_COND_FAC as f64 * C0 + 1e-9f32 as f64; + CAb[0 as usize] = CAf[0 as usize]; + invGain = 1.0f32 as f64; + reached_max_gain = 0; + n = 0; + while n < D { + s = 0; + while s < nb_subfr { + x_ptr = x.offset((s * subfr_length) as isize); + tmp1 = *x_ptr.offset(n as isize) as f64; + tmp2 = *x_ptr.offset((subfr_length - n - 1) as isize) as f64; + k = 0; + while k < n { + C_first_row[k as usize] -= + (*x_ptr.offset(n as isize) * *x_ptr.offset((n - k - 1) as isize)) as f64; + C_last_row[k as usize] -= (*x_ptr.offset((subfr_length - n - 1) as isize) + * *x_ptr.offset((subfr_length - n + k) as isize)) + as f64; + Atmp = Af[k as usize]; + tmp1 += *x_ptr.offset((n - k - 1) as isize) as f64 * Atmp; + tmp2 += *x_ptr.offset((subfr_length - n + k) as isize) as f64 * Atmp; + k += 1; + } + k = 0; + while k <= n { + CAf[k as usize] -= tmp1 * *x_ptr.offset((n - k) as isize) as f64; + CAb[k as usize] -= tmp2 * *x_ptr.offset((subfr_length - n + k - 1) as isize) as f64; + k += 1; + } + s += 1; + } + tmp1 = C_first_row[n as usize]; + tmp2 = C_last_row[n as usize]; + k = 0; + while k < n { + Atmp = Af[k as usize]; + tmp1 += C_last_row[(n - k - 1) as usize] * Atmp; + tmp2 += C_first_row[(n - k - 1) as usize] * Atmp; + k += 1; + } + CAf[(n + 1) as usize] = tmp1; + CAb[(n + 1) as usize] = tmp2; + num = CAb[(n + 1) as usize]; + nrg_b = CAb[0 as usize]; + nrg_f = CAf[0 as usize]; + k = 0; + while k < n { + Atmp = Af[k as usize]; + num += CAb[(n - k) as usize] * Atmp; + nrg_b += CAb[(k + 1) as usize] * Atmp; + nrg_f += CAf[(k + 1) as usize] * Atmp; + k += 1; + } + rc = -2.0f64 * num / (nrg_f + nrg_b); + tmp1 = invGain * (1.0f64 - rc * rc); + if tmp1 <= minInvGain as f64 { + rc = (1.0f64 - minInvGain as f64 / invGain).sqrt(); + if num > 0 as f64 { + rc = -rc; + } + invGain = minInvGain as f64; + reached_max_gain = 1; + } else { + invGain = tmp1; + } + k = 0; + while k < n + 1 >> 1 { + tmp1 = Af[k as usize]; + tmp2 = Af[(n - k - 1) as usize]; + Af[k as usize] = tmp1 + rc * tmp2; + Af[(n - k - 1) as usize] = tmp2 + rc * tmp1; + k += 1; + } + Af[n as usize] = rc; + if reached_max_gain != 0 { + k = n + 1; + while k < D { + Af[k as usize] = 0.0f64; + k += 1; + } + break; + } else { + k = 0; + while k <= n + 1 { + tmp1 = CAf[k as usize]; + CAf[k as usize] += rc * CAb[(n - k + 1) as usize]; + CAb[(n - k + 1) as usize] += rc * tmp1; + k += 1; + } + n += 1; + } + } + if reached_max_gain != 0 { + k = 0; + while k < D { + *A.offset(k as isize) = -Af[k as usize] as f32; + k += 1; + } + s = 0; + while s < nb_subfr { + C0 -= silk_energy_FLP(x.offset((s * subfr_length) as isize), D); + s += 1; + } + nrg_f = C0 * invGain; + } else { + nrg_f = CAf[0 as usize]; + tmp1 = 1.0f64; + k = 0; + while k < D { + Atmp = Af[k as usize]; + nrg_f += CAf[(k + 1) as usize] * Atmp; + tmp1 += Atmp * Atmp; + *A.offset(k as isize) = -Atmp as f32; + k += 1; + } + nrg_f -= FIND_LPC_COND_FAC as f64 * C0 * tmp1; + } + return nrg_f as f32; +} diff --git a/vendor/unsafe-libopus/src/silk/float/bwexpander_FLP.rs b/vendor/unsafe-libopus/src/silk/float/bwexpander_FLP.rs new file mode 100644 index 00000000..0a2e0178 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/bwexpander_FLP.rs @@ -0,0 +1,11 @@ +pub unsafe fn silk_bwexpander_FLP(ar: *mut f32, d: i32, chirp: f32) { + let mut i: i32 = 0; + let mut cfac: f32 = chirp; + i = 0; + while i < d - 1 { + *ar.offset(i as isize) *= cfac; + cfac *= chirp; + i += 1; + } + *ar.offset((d - 1) as isize) *= cfac; +} diff --git a/vendor/unsafe-libopus/src/silk/float/corrMatrix_FLP.rs b/vendor/unsafe-libopus/src/silk/float/corrMatrix_FLP.rs new file mode 100644 index 00000000..da5d6457 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/corrMatrix_FLP.rs @@ -0,0 +1,50 @@ +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::inner_product_FLP::silk_inner_product_FLP; + +pub unsafe fn silk_corrVector_FLP(x: *const f32, t: *const f32, L: i32, Order: i32, Xt: *mut f32) { + let mut lag: i32 = 0; + let mut ptr1: *const f32 = 0 as *const f32; + ptr1 = &*x.offset((Order - 1) as isize) as *const f32; + lag = 0; + while lag < Order { + *Xt.offset(lag as isize) = silk_inner_product_FLP(ptr1, t, L) as f32; + ptr1 = ptr1.offset(-1); + lag += 1; + } +} +pub unsafe fn silk_corrMatrix_FLP(x: *const f32, L: i32, Order: i32, XX: *mut f32) { + let mut j: i32 = 0; + let mut lag: i32 = 0; + let mut energy: f64 = 0.; + let mut ptr1: *const f32 = 0 as *const f32; + let mut ptr2: *const f32 = 0 as *const f32; + ptr1 = &*x.offset((Order - 1) as isize) as *const f32; + energy = silk_energy_FLP(ptr1, L); + *XX.offset((0 * Order + 0) as isize) = energy as f32; + j = 1; + while j < Order { + energy += (*ptr1.offset(-j as isize) * *ptr1.offset(-j as isize) + - *ptr1.offset((L - j) as isize) * *ptr1.offset((L - j) as isize)) + as f64; + *XX.offset((j * Order + j) as isize) = energy as f32; + j += 1; + } + ptr2 = &*x.offset((Order - 2) as isize) as *const f32; + lag = 1; + while lag < Order { + energy = silk_inner_product_FLP(ptr1, ptr2, L); + *XX.offset((lag * Order + 0) as isize) = energy as f32; + *XX.offset((0 * Order + lag) as isize) = energy as f32; + j = 1; + while j < Order - lag { + energy += (*ptr1.offset(-j as isize) * *ptr2.offset(-j as isize) + - *ptr1.offset((L - j) as isize) * *ptr2.offset((L - j) as isize)) + as f64; + *XX.offset(((lag + j) * Order + j) as isize) = energy as f32; + *XX.offset((j * Order + (lag + j)) as isize) = energy as f32; + j += 1; + } + ptr2 = ptr2.offset(-1); + lag += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/encode_frame_FLP.rs b/vendor/unsafe-libopus/src/silk/float/encode_frame_FLP.rs new file mode 100644 index 00000000..4e474b53 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/encode_frame_FLP.rs @@ -0,0 +1,576 @@ +pub mod SigProc_FLP_h { + #[inline] + pub unsafe fn silk_short2float_array(out: *mut f32, in_0: *const i16, length: i32) { + let mut k: i32 = 0; + k = length - 1; + while k >= 0 { + *out.offset(k as isize) = *in_0.offset(k as isize) as f32; + k -= 1; + } + } +} +pub use self::SigProc_FLP_h::silk_short2float_array; +use crate::celt::entcode::{ec_ctx_saved, ec_tell}; +use crate::celt::entenc::ec_enc; +use crate::externs::{memcpy, memmove}; +use crate::silk::define::{ + CODE_CONDITIONALLY, LA_SHAPE_MS, MAX_CONSECUTIVE_DTX, NB_SPEECH_FRAMES_BEFORE_DTX, + N_LEVELS_QGAIN, TYPE_NO_VOICE_ACTIVITY, TYPE_UNVOICED, VAD_NO_ACTIVITY, +}; +use crate::silk::encode_indices::silk_encode_indices; +use crate::silk::encode_pulses::silk_encode_pulses; +use crate::silk::float::find_pitch_lags_FLP::silk_find_pitch_lags_FLP; +use crate::silk::float::find_pred_coefs_FLP::silk_find_pred_coefs_FLP; +use crate::silk::float::noise_shape_analysis_FLP::silk_noise_shape_analysis_FLP; +use crate::silk::float::process_gains_FLP::silk_process_gains_FLP; +use crate::silk::float::structs_FLP::{silk_encoder_control_FLP, silk_encoder_state_FLP}; +use crate::silk::float::wrappers_FLP::silk_NSQ_wrapper_FLP; +use crate::silk::gain_quant::{silk_gains_ID, silk_gains_dequant, silk_gains_quant}; +use crate::silk::log2lin::silk_log2lin; +use crate::silk::structs::{silk_nsq_state, SideInfoIndices}; +use crate::silk::LP_variable_cutoff::silk_LP_variable_cutoff; +use crate::silk::SigProc_FIX::silk_min_int; +use crate::silk::VAD::silk_VAD_GetSA_Q8_c; + +pub unsafe fn silk_encode_do_VAD_FLP(psEnc: *mut silk_encoder_state_FLP, activity: i32) { + let activity_threshold: i32 = ((0.05f32 * ((1) << 8) as f32) as f64 + 0.5f64) as i32; + silk_VAD_GetSA_Q8_c( + &mut (*psEnc).sCmn, + ((*psEnc).sCmn.inputBuf).as_mut_ptr().offset(1 as isize) as *const i16, + ); + if activity == VAD_NO_ACTIVITY && (*psEnc).sCmn.speech_activity_Q8 >= activity_threshold { + (*psEnc).sCmn.speech_activity_Q8 = activity_threshold - 1; + } + if (*psEnc).sCmn.speech_activity_Q8 < activity_threshold { + (*psEnc).sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY as i8; + (*psEnc).sCmn.noSpeechCounter += 1; + if (*psEnc).sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX { + (*psEnc).sCmn.inDTX = 0; + } else if (*psEnc).sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX + { + (*psEnc).sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; + (*psEnc).sCmn.inDTX = 0; + } + (*psEnc).sCmn.VAD_flags[(*psEnc).sCmn.nFramesEncoded as usize] = 0; + } else { + (*psEnc).sCmn.noSpeechCounter = 0; + (*psEnc).sCmn.inDTX = 0; + (*psEnc).sCmn.indices.signalType = TYPE_UNVOICED as i8; + (*psEnc).sCmn.VAD_flags[(*psEnc).sCmn.nFramesEncoded as usize] = 1; + }; +} +pub unsafe fn silk_encode_frame_FLP( + psEnc: *mut silk_encoder_state_FLP, + pnBytesOut: *mut i32, + mut psRangeEnc: Option<&mut ec_enc>, + condCoding: i32, + maxBits: i32, + useCBR: i32, +) -> i32 { + let mut sEncCtrl: silk_encoder_control_FLP = silk_encoder_control_FLP { + Gains: [0.; 4], + PredCoef: [[0.; 16]; 2], + LTPCoef: [0.; 20], + LTP_scale: 0., + pitchL: [0; 4], + AR: [0.; 96], + LF_MA_shp: [0.; 4], + LF_AR_shp: [0.; 4], + Tilt: [0.; 4], + HarmShapeGain: [0.; 4], + Lambda: 0., + input_quality: 0., + coding_quality: 0., + predGain: 0., + LTPredCodGain: 0., + ResNrg: [0.; 4], + GainsUnq_Q16: [0; 4], + lastGainIndexPrev: 0, + }; + let mut i: i32 = 0; + let mut iter: i32 = 0; + let mut maxIter: i32 = 0; + let mut found_upper: i32 = 0; + let mut found_lower: i32 = 0; + let ret: i32 = 0; + let mut x_frame: *mut f32 = 0 as *mut f32; + let mut res_pitch_frame: *mut f32 = 0 as *mut f32; + let mut res_pitch: [f32; 672] = [0.; 672]; + let mut sRangeEnc_copy = ec_ctx_saved::default(); + let mut sRangeEnc_copy2 = ec_ctx_saved::default(); + let mut sNSQ_copy: silk_nsq_state = silk_nsq_state { + xq: [0; 640], + sLTP_shp_Q14: [0; 640], + sLPC_Q14: [0; 96], + sAR2_Q14: [0; 24], + sLF_AR_shp_Q14: 0, + sDiff_shp_Q14: 0, + lagPrev: 0, + sLTP_buf_idx: 0, + sLTP_shp_buf_idx: 0, + rand_seed: 0, + prev_gain_Q16: 0, + rewhite_flag: 0, + }; + let mut sNSQ_copy2: silk_nsq_state = silk_nsq_state { + xq: [0; 640], + sLTP_shp_Q14: [0; 640], + sLPC_Q14: [0; 96], + sAR2_Q14: [0; 24], + sLF_AR_shp_Q14: 0, + sDiff_shp_Q14: 0, + lagPrev: 0, + sLTP_buf_idx: 0, + sLTP_shp_buf_idx: 0, + rand_seed: 0, + prev_gain_Q16: 0, + rewhite_flag: 0, + }; + let mut seed_copy: i32 = 0; + let mut nBits: i32 = 0; + let mut nBits_lower: i32 = 0; + let mut nBits_upper: i32 = 0; + let mut gainMult_lower: i32 = 0; + let mut gainMult_upper: i32 = 0; + let mut gainsID: i32 = 0; + let mut gainsID_lower: i32 = 0; + let mut gainsID_upper: i32 = 0; + let mut gainMult_Q8: i16 = 0; + let mut ec_prevLagIndex_copy: i16 = 0; + let mut ec_prevSignalType_copy: i32 = 0; + let mut LastGainIndex_copy2: i8 = 0; + let mut pGains_Q16: [i32; 4] = [0; 4]; + let mut ec_buf_copy: [u8; 1275] = [0; 1275]; + let mut gain_lock: [i32; 4] = [0, 0, 0, 0]; + let mut best_gain_mult: [i16; 4] = [0; 4]; + let mut best_sum: [i32; 4] = [0; 4]; + gainMult_upper = 0; + gainMult_lower = gainMult_upper; + nBits_upper = gainMult_lower; + nBits_lower = nBits_upper; + LastGainIndex_copy2 = nBits_lower as i8; + let fresh0 = (*psEnc).sCmn.frameCounter; + (*psEnc).sCmn.frameCounter = (*psEnc).sCmn.frameCounter + 1; + (*psEnc).sCmn.indices.Seed = (fresh0 & 3) as i8; + x_frame = ((*psEnc).x_buf) + .as_mut_ptr() + .offset((*psEnc).sCmn.ltp_mem_length as isize); + res_pitch_frame = res_pitch + .as_mut_ptr() + .offset((*psEnc).sCmn.ltp_mem_length as isize); + silk_LP_variable_cutoff( + &mut (*psEnc).sCmn.sLP, + ((*psEnc).sCmn.inputBuf).as_mut_ptr().offset(1 as isize), + (*psEnc).sCmn.frame_length, + ); + silk_short2float_array( + x_frame.offset((LA_SHAPE_MS * (*psEnc).sCmn.fs_kHz) as isize), + ((*psEnc).sCmn.inputBuf).as_mut_ptr().offset(1 as isize), + (*psEnc).sCmn.frame_length, + ); + i = 0; + while i < 8 { + *x_frame.offset( + (LA_SHAPE_MS * (*psEnc).sCmn.fs_kHz + i * ((*psEnc).sCmn.frame_length >> 3)) as isize, + ) += (1 - (i & 2)) as f32 * 1e-6f32; + i += 1; + } + if (*psEnc).sCmn.prefillFlag == 0 { + let psRangeEnc = &mut **psRangeEnc.as_mut().unwrap(); + + silk_find_pitch_lags_FLP( + psEnc, + &mut sEncCtrl, + res_pitch.as_mut_ptr(), + x_frame as *const f32, + (*psEnc).sCmn.arch, + ); + silk_noise_shape_analysis_FLP(psEnc, &mut sEncCtrl, res_pitch_frame, x_frame); + silk_find_pred_coefs_FLP( + psEnc, + &mut sEncCtrl, + res_pitch_frame as *const f32, + x_frame as *const f32, + condCoding, + ); + silk_process_gains_FLP(psEnc, &mut sEncCtrl, condCoding); + silk_LBRR_encode_FLP(psEnc, &mut sEncCtrl, x_frame as *const f32, condCoding); + maxIter = 6; + gainMult_Q8 = ((1 * ((1) << 8)) as f64 + 0.5f64) as i32 as i16; + found_lower = 0; + found_upper = 0; + gainsID = silk_gains_ID( + ((*psEnc).sCmn.indices.GainsIndices).as_mut_ptr() as *const i8, + (*psEnc).sCmn.nb_subfr, + ); + gainsID_lower = -1; + gainsID_upper = -1; + sRangeEnc_copy = psRangeEnc.save(); + memcpy( + &mut sNSQ_copy as *mut silk_nsq_state as *mut core::ffi::c_void, + &mut (*psEnc).sCmn.sNSQ as *mut silk_nsq_state as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + seed_copy = (*psEnc).sCmn.indices.Seed as i32; + ec_prevLagIndex_copy = (*psEnc).sCmn.ec_prevLagIndex; + ec_prevSignalType_copy = (*psEnc).sCmn.ec_prevSignalType; + iter = 0; + loop { + if gainsID == gainsID_lower { + nBits = nBits_lower; + } else if gainsID == gainsID_upper { + nBits = nBits_upper; + } else { + if iter > 0 { + psRangeEnc.restore(sRangeEnc_copy); + memcpy( + &mut (*psEnc).sCmn.sNSQ as *mut silk_nsq_state as *mut core::ffi::c_void, + &mut sNSQ_copy as *mut silk_nsq_state as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + (*psEnc).sCmn.indices.Seed = seed_copy as i8; + (*psEnc).sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; + (*psEnc).sCmn.ec_prevSignalType = ec_prevSignalType_copy; + } + silk_NSQ_wrapper_FLP( + psEnc, + &mut sEncCtrl, + &mut (*psEnc).sCmn.indices, + &mut (*psEnc).sCmn.sNSQ, + ((*psEnc).sCmn.pulses).as_mut_ptr(), + x_frame as *const f32, + ); + if iter == maxIter && found_lower == 0 { + sRangeEnc_copy2 = psRangeEnc.save(); + } + silk_encode_indices( + &mut (*psEnc).sCmn, + psRangeEnc, + (*psEnc).sCmn.nFramesEncoded, + 0, + condCoding, + ); + silk_encode_pulses( + psRangeEnc, + (*psEnc).sCmn.indices.signalType as i32, + (*psEnc).sCmn.indices.quantOffsetType as i32, + &mut (*psEnc).sCmn.pulses, + (*psEnc).sCmn.frame_length, + ); + nBits = ec_tell(psRangeEnc); + if iter == maxIter && found_lower == 0 && nBits > maxBits { + psRangeEnc.restore(sRangeEnc_copy2); + (*psEnc).sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + (*psEnc).sCmn.indices.GainsIndices[i as usize] = 4; + i += 1; + } + if condCoding != CODE_CONDITIONALLY { + (*psEnc).sCmn.indices.GainsIndices[0 as usize] = sEncCtrl.lastGainIndexPrev; + } + (*psEnc).sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; + (*psEnc).sCmn.ec_prevSignalType = ec_prevSignalType_copy; + i = 0; + while i < (*psEnc).sCmn.frame_length { + (*psEnc).sCmn.pulses[i as usize] = 0; + i += 1; + } + silk_encode_indices( + &mut (*psEnc).sCmn, + psRangeEnc, + (*psEnc).sCmn.nFramesEncoded, + 0, + condCoding, + ); + silk_encode_pulses( + psRangeEnc, + (*psEnc).sCmn.indices.signalType as i32, + (*psEnc).sCmn.indices.quantOffsetType as i32, + &mut (*psEnc).sCmn.pulses, + (*psEnc).sCmn.frame_length, + ); + nBits = ec_tell(psRangeEnc); + } + if useCBR == 0 && iter == 0 && nBits <= maxBits { + break; + } + } + if iter == maxIter { + if found_lower != 0 && (gainsID == gainsID_lower || nBits > maxBits) { + psRangeEnc.restore(sRangeEnc_copy2); + assert!(sRangeEnc_copy2.offs <= 1275); + memcpy( + (*psRangeEnc).buf.as_mut_ptr() as *mut core::ffi::c_void, + ec_buf_copy.as_mut_ptr() as *const core::ffi::c_void, + sRangeEnc_copy2.offs as u64, + ); + memcpy( + &mut (*psEnc).sCmn.sNSQ as *mut silk_nsq_state as *mut core::ffi::c_void, + &mut sNSQ_copy2 as *mut silk_nsq_state as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + (*psEnc).sShape.LastGainIndex = LastGainIndex_copy2; + } + break; + } else { + if nBits > maxBits { + if found_lower == 0 && iter >= 2 { + sEncCtrl.Lambda = if sEncCtrl.Lambda * 1.5f32 > 1.5f32 { + sEncCtrl.Lambda * 1.5f32 + } else { + 1.5f32 + }; + (*psEnc).sCmn.indices.quantOffsetType = 0; + found_upper = 0; + gainsID_upper = -1; + } else { + found_upper = 1; + nBits_upper = nBits; + gainMult_upper = gainMult_Q8 as i32; + gainsID_upper = gainsID; + } + } else { + if !(nBits < maxBits - 5) { + break; + } + found_lower = 1; + nBits_lower = nBits; + gainMult_lower = gainMult_Q8 as i32; + if gainsID != gainsID_lower { + gainsID_lower = gainsID; + sRangeEnc_copy2 = psRangeEnc.save(); + assert!((*psRangeEnc).offs <= 1275); + memcpy( + ec_buf_copy.as_mut_ptr() as *mut core::ffi::c_void, + (*psRangeEnc).buf.as_mut_ptr() as *const core::ffi::c_void, + (*psRangeEnc).offs as u64, + ); + memcpy( + &mut sNSQ_copy2 as *mut silk_nsq_state as *mut core::ffi::c_void, + &mut (*psEnc).sCmn.sNSQ as *mut silk_nsq_state + as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + LastGainIndex_copy2 = (*psEnc).sShape.LastGainIndex; + } + } + if found_lower == 0 && nBits > maxBits { + let mut j: i32 = 0; + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + let mut sum: i32 = 0; + j = i * (*psEnc).sCmn.subfr_length; + while j < (i + 1) * (*psEnc).sCmn.subfr_length { + sum += ((*psEnc).sCmn.pulses[j as usize] as i32).abs(); + j += 1; + } + if iter == 0 || sum < best_sum[i as usize] && gain_lock[i as usize] == 0 { + best_sum[i as usize] = sum; + best_gain_mult[i as usize] = gainMult_Q8; + } else { + gain_lock[i as usize] = 1; + } + i += 1; + } + } + if found_lower & found_upper == 0 { + if nBits > maxBits { + if (gainMult_Q8 as i32) < 16384 { + gainMult_Q8 = (gainMult_Q8 as i32 * 2) as i16; + } else { + gainMult_Q8 = 32767; + } + } else { + let mut gain_factor_Q16: i32 = 0; + gain_factor_Q16 = silk_log2lin( + (((nBits - maxBits) as u32) << 7) as i32 / (*psEnc).sCmn.frame_length + + ((16 * ((1) << 7)) as f64 + 0.5f64) as i32, + ); + gainMult_Q8 = + (gain_factor_Q16 as i64 * gainMult_Q8 as i64 >> 16) as i32 as i16; + } + } else { + gainMult_Q8 = (gainMult_lower + + (gainMult_upper - gainMult_lower) * (maxBits - nBits_lower) + / (nBits_upper - nBits_lower)) as i16; + if gainMult_Q8 as i32 > gainMult_lower + (gainMult_upper - gainMult_lower >> 2) + { + gainMult_Q8 = + (gainMult_lower + (gainMult_upper - gainMult_lower >> 2)) as i16; + } else if (gainMult_Q8 as i32) + < gainMult_upper - (gainMult_upper - gainMult_lower >> 2) + { + gainMult_Q8 = + (gainMult_upper - (gainMult_upper - gainMult_lower >> 2)) as i16; + } + } + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + let mut tmp: i16 = 0; + if gain_lock[i as usize] != 0 { + tmp = best_gain_mult[i as usize]; + } else { + tmp = gainMult_Q8; + } + pGains_Q16[i as usize] = (((if 0x80000000 as u32 as i32 >> 8 > 0x7fffffff >> 8 { + if (sEncCtrl.GainsUnq_Q16[i as usize] as i64 * tmp as i64 >> 16) as i32 + > 0x80000000 as u32 as i32 >> 8 + { + 0x80000000 as u32 as i32 >> 8 + } else { + if ((sEncCtrl.GainsUnq_Q16[i as usize] as i64 * tmp as i64 >> 16) + as i32) + < 0x7fffffff >> 8 + { + 0x7fffffff >> 8 + } else { + (sEncCtrl.GainsUnq_Q16[i as usize] as i64 * tmp as i64 >> 16) as i32 + } + } + } else { + if (sEncCtrl.GainsUnq_Q16[i as usize] as i64 * tmp as i64 >> 16) as i32 + > 0x7fffffff >> 8 + { + 0x7fffffff >> 8 + } else { + if ((sEncCtrl.GainsUnq_Q16[i as usize] as i64 * tmp as i64 >> 16) + as i32) + < 0x80000000 as u32 as i32 >> 8 + { + 0x80000000 as u32 as i32 >> 8 + } else { + (sEncCtrl.GainsUnq_Q16[i as usize] as i64 * tmp as i64 >> 16) as i32 + } + } + }) as u32) + << 8) as i32; + i += 1; + } + (*psEnc).sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; + silk_gains_quant( + ((*psEnc).sCmn.indices.GainsIndices).as_mut_ptr(), + pGains_Q16.as_mut_ptr(), + &mut (*psEnc).sShape.LastGainIndex, + (condCoding == CODE_CONDITIONALLY) as i32, + (*psEnc).sCmn.nb_subfr, + ); + gainsID = silk_gains_ID( + ((*psEnc).sCmn.indices.GainsIndices).as_mut_ptr() as *const i8, + (*psEnc).sCmn.nb_subfr, + ); + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + sEncCtrl.Gains[i as usize] = pGains_Q16[i as usize] as f32 / 65536.0f32; + i += 1; + } + iter += 1; + } + } + } + memmove( + ((*psEnc).x_buf).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*psEnc).x_buf) + .as_mut_ptr() + .offset((*psEnc).sCmn.frame_length as isize) as *mut f32 + as *const core::ffi::c_void, + (((*psEnc).sCmn.ltp_mem_length + 5 * (*psEnc).sCmn.fs_kHz) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + if (*psEnc).sCmn.prefillFlag != 0 { + *pnBytesOut = 0; + return ret; + } + (*psEnc).sCmn.prevLag = sEncCtrl.pitchL[((*psEnc).sCmn.nb_subfr - 1) as usize]; + (*psEnc).sCmn.prevSignalType = (*psEnc).sCmn.indices.signalType; + (*psEnc).sCmn.first_frame_after_reset = 0; + *pnBytesOut = (ec_tell(psRangeEnc.unwrap()) + 7) >> 3; + + ret +} +#[inline] +unsafe fn silk_LBRR_encode_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + xfw: *const f32, + condCoding: i32, +) { + let mut k: i32 = 0; + let mut Gains_Q16: [i32; 4] = [0; 4]; + let mut TempGains: [f32; 4] = [0.; 4]; + let psIndices_LBRR: *mut SideInfoIndices = &mut *((*psEnc).sCmn.indices_LBRR) + .as_mut_ptr() + .offset((*psEnc).sCmn.nFramesEncoded as isize) + as *mut SideInfoIndices; + let mut sNSQ_LBRR: silk_nsq_state = silk_nsq_state { + xq: [0; 640], + sLTP_shp_Q14: [0; 640], + sLPC_Q14: [0; 96], + sAR2_Q14: [0; 24], + sLF_AR_shp_Q14: 0, + sDiff_shp_Q14: 0, + lagPrev: 0, + sLTP_buf_idx: 0, + sLTP_shp_buf_idx: 0, + rand_seed: 0, + prev_gain_Q16: 0, + rewhite_flag: 0, + }; + if (*psEnc).sCmn.LBRR_enabled != 0 + && (*psEnc).sCmn.speech_activity_Q8 > ((0.3f32 * ((1) << 8) as f32) as f64 + 0.5f64) as i32 + { + (*psEnc).sCmn.LBRR_flags[(*psEnc).sCmn.nFramesEncoded as usize] = 1; + memcpy( + &mut sNSQ_LBRR as *mut silk_nsq_state as *mut core::ffi::c_void, + &mut (*psEnc).sCmn.sNSQ as *mut silk_nsq_state as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + memcpy( + psIndices_LBRR as *mut core::ffi::c_void, + &mut (*psEnc).sCmn.indices as *mut SideInfoIndices as *const core::ffi::c_void, + ::core::mem::size_of::() as u64, + ); + memcpy( + TempGains.as_mut_ptr() as *mut core::ffi::c_void, + ((*psEncCtrl).Gains).as_mut_ptr() as *const core::ffi::c_void, + ((*psEnc).sCmn.nb_subfr as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + if (*psEnc).sCmn.nFramesEncoded == 0 + || (*psEnc).sCmn.LBRR_flags[((*psEnc).sCmn.nFramesEncoded - 1) as usize] == 0 + { + (*psEnc).sCmn.LBRRprevLastGainIndex = (*psEnc).sShape.LastGainIndex; + (*psIndices_LBRR).GainsIndices[0 as usize] = + ((*psIndices_LBRR).GainsIndices[0 as usize] as i32 + + (*psEnc).sCmn.LBRR_GainIncreases) as i8; + (*psIndices_LBRR).GainsIndices[0 as usize] = silk_min_int( + (*psIndices_LBRR).GainsIndices[0 as usize] as i32, + N_LEVELS_QGAIN - 1, + ) as i8; + } + silk_gains_dequant( + Gains_Q16.as_mut_ptr(), + ((*psIndices_LBRR).GainsIndices).as_mut_ptr() as *const i8, + &mut (*psEnc).sCmn.LBRRprevLastGainIndex, + (condCoding == CODE_CONDITIONALLY) as i32, + (*psEnc).sCmn.nb_subfr, + ); + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + (*psEncCtrl).Gains[k as usize] = Gains_Q16[k as usize] as f32 * (1.0f32 / 65536.0f32); + k += 1; + } + silk_NSQ_wrapper_FLP( + psEnc, + psEncCtrl, + psIndices_LBRR, + &mut sNSQ_LBRR, + ((*psEnc).sCmn.pulses_LBRR[(*psEnc).sCmn.nFramesEncoded as usize]).as_mut_ptr(), + xfw, + ); + memcpy( + ((*psEncCtrl).Gains).as_mut_ptr() as *mut core::ffi::c_void, + TempGains.as_mut_ptr() as *const core::ffi::c_void, + ((*psEnc).sCmn.nb_subfr as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/energy_FLP.rs b/vendor/unsafe-libopus/src/silk/float/energy_FLP.rs new file mode 100644 index 00000000..561da048 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/energy_FLP.rs @@ -0,0 +1,18 @@ +pub unsafe fn silk_energy_FLP(data: *const f32, dataSize: i32) -> f64 { + let mut i: i32 = 0; + let mut result: f64 = 0.; + result = 0.0f64; + i = 0; + while i < dataSize - 3 { + result += *data.offset((i + 0) as isize) as f64 * *data.offset((i + 0) as isize) as f64 + + *data.offset((i + 1) as isize) as f64 * *data.offset((i + 1) as isize) as f64 + + *data.offset((i + 2) as isize) as f64 * *data.offset((i + 2) as isize) as f64 + + *data.offset((i + 3) as isize) as f64 * *data.offset((i + 3) as isize) as f64; + i += 4; + } + while i < dataSize { + result += *data.offset(i as isize) as f64 * *data.offset(i as isize) as f64; + i += 1; + } + return result; +} diff --git a/vendor/unsafe-libopus/src/silk/float/find_LPC_FLP.rs b/vendor/unsafe-libopus/src/silk/float/find_LPC_FLP.rs new file mode 100644 index 00000000..6b769aab --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/find_LPC_FLP.rs @@ -0,0 +1,114 @@ +pub mod float_h { + pub const FLT_MAX: f32 = __FLT_MAX__; + use super::internal::__FLT_MAX__; +} +pub mod typedef_h { + pub const silk_float_MAX: f32 = FLT_MAX; + use super::float_h::FLT_MAX; +} +pub mod internal { + pub const __FLT_MAX__: f32 = 3.40282347e+38f32; +} +pub use self::float_h::FLT_MAX; +pub use self::internal::__FLT_MAX__; +pub use self::typedef_h::silk_float_MAX; +use crate::silk::define::MAX_NB_SUBFR; +use crate::silk::float::burg_modified_FLP::silk_burg_modified_FLP; +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::wrappers_FLP::{silk_A2NLSF_FLP, silk_NLSF2A_FLP}; +use crate::silk::float::LPC_analysis_filter_FLP::silk_LPC_analysis_filter_FLP; +use crate::silk::interpolate::silk_interpolate; +use crate::silk::structs::silk_encoder_state; + +pub unsafe fn silk_find_LPC_FLP( + psEncC: *mut silk_encoder_state, + NLSF_Q15: *mut i16, + x: *const f32, + minInvGain: f32, +) { + let mut k: i32 = 0; + let mut subfr_length: i32 = 0; + let mut a: [f32; 16] = [0.; 16]; + let mut res_nrg: f32 = 0.; + let mut res_nrg_2nd: f32 = 0.; + let mut res_nrg_interp: f32 = 0.; + let mut NLSF0_Q15: [i16; 16] = [0; 16]; + let mut a_tmp: [f32; 16] = [0.; 16]; + let mut LPC_res: [f32; 384] = [0.; 384]; + subfr_length = (*psEncC).subfr_length + (*psEncC).predictLPCOrder; + (*psEncC).indices.NLSFInterpCoef_Q2 = 4; + res_nrg = silk_burg_modified_FLP( + a.as_mut_ptr(), + x, + minInvGain, + subfr_length, + (*psEncC).nb_subfr, + (*psEncC).predictLPCOrder, + ); + if (*psEncC).useInterpolatedNLSFs != 0 + && (*psEncC).first_frame_after_reset == 0 + && (*psEncC).nb_subfr == MAX_NB_SUBFR + { + res_nrg -= silk_burg_modified_FLP( + a_tmp.as_mut_ptr(), + x.offset((MAX_NB_SUBFR / 2 * subfr_length) as isize), + minInvGain, + subfr_length, + MAX_NB_SUBFR / 2, + (*psEncC).predictLPCOrder, + ); + silk_A2NLSF_FLP(NLSF_Q15, a_tmp.as_mut_ptr(), (*psEncC).predictLPCOrder); + res_nrg_2nd = silk_float_MAX; + k = 3; + while k >= 0 { + silk_interpolate( + &mut NLSF0_Q15[..(*psEncC).predictLPCOrder as usize], + &(*psEncC).prev_NLSFq_Q15[..(*psEncC).predictLPCOrder as usize], + std::slice::from_raw_parts(NLSF_Q15, (*psEncC).predictLPCOrder as usize), + k, + ); + silk_NLSF2A_FLP( + a_tmp.as_mut_ptr(), + NLSF0_Q15.as_mut_ptr(), + (*psEncC).predictLPCOrder, + (*psEncC).arch, + ); + silk_LPC_analysis_filter_FLP( + LPC_res.as_mut_ptr(), + a_tmp.as_mut_ptr() as *const f32, + x, + 2 * subfr_length, + (*psEncC).predictLPCOrder, + ); + res_nrg_interp = (silk_energy_FLP( + LPC_res + .as_mut_ptr() + .offset((*psEncC).predictLPCOrder as isize), + subfr_length - (*psEncC).predictLPCOrder, + ) + silk_energy_FLP( + LPC_res + .as_mut_ptr() + .offset((*psEncC).predictLPCOrder as isize) + .offset(subfr_length as isize), + subfr_length - (*psEncC).predictLPCOrder, + )) as f32; + if res_nrg_interp < res_nrg { + res_nrg = res_nrg_interp; + (*psEncC).indices.NLSFInterpCoef_Q2 = k as i8; + } else if res_nrg_interp > res_nrg_2nd { + break; + } + res_nrg_2nd = res_nrg_interp; + k -= 1; + } + } + if (*psEncC).indices.NLSFInterpCoef_Q2 as i32 == 4 { + silk_A2NLSF_FLP(NLSF_Q15, a.as_mut_ptr(), (*psEncC).predictLPCOrder); + } + assert!( + (*psEncC).indices.NLSFInterpCoef_Q2 as i32 == 4 + || (*psEncC).useInterpolatedNLSFs != 0 + && (*psEncC).first_frame_after_reset == 0 + && (*psEncC).nb_subfr == 4 + ); +} diff --git a/vendor/unsafe-libopus/src/silk/float/find_LTP_FLP.rs b/vendor/unsafe-libopus/src/silk/float/find_LTP_FLP.rs new file mode 100644 index 00000000..51b0232a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/find_LTP_FLP.rs @@ -0,0 +1,45 @@ +use crate::silk::define::LTP_ORDER; +use crate::silk::float::corrMatrix_FLP::{silk_corrMatrix_FLP, silk_corrVector_FLP}; +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::scale_vector_FLP::silk_scale_vector_FLP; + +pub unsafe fn silk_find_LTP_FLP( + XX: *mut f32, + xX: *mut f32, + mut r_ptr: *const f32, + lag: *const i32, + subfr_length: i32, + nb_subfr: i32, +) { + let mut k: i32 = 0; + let mut xX_ptr: *mut f32 = 0 as *mut f32; + let mut XX_ptr: *mut f32 = 0 as *mut f32; + let mut lag_ptr: *const f32 = 0 as *const f32; + let mut xx: f32 = 0.; + let mut temp: f32 = 0.; + xX_ptr = xX; + XX_ptr = XX; + k = 0; + while k < nb_subfr { + lag_ptr = r_ptr.offset(-((*lag.offset(k as isize) + LTP_ORDER / 2) as isize)); + silk_corrMatrix_FLP(lag_ptr, subfr_length, LTP_ORDER, XX_ptr); + silk_corrVector_FLP(lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr); + xx = silk_energy_FLP(r_ptr, subfr_length + LTP_ORDER) as f32; + temp = 1.0f32 + / (if xx + > 0.03f32 * 0.5f32 * (*XX_ptr.offset(0 as isize) + *XX_ptr.offset(24 as isize)) + + 1.0f32 + { + xx + } else { + 0.03f32 * 0.5f32 * (*XX_ptr.offset(0 as isize) + *XX_ptr.offset(24 as isize)) + + 1.0f32 + }); + silk_scale_vector_FLP(XX_ptr, temp, LTP_ORDER * LTP_ORDER); + silk_scale_vector_FLP(xX_ptr, temp, LTP_ORDER); + r_ptr = r_ptr.offset(subfr_length as isize); + XX_ptr = XX_ptr.offset((LTP_ORDER * LTP_ORDER) as isize); + xX_ptr = xX_ptr.offset(LTP_ORDER as isize); + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/find_pitch_lags_FLP.rs b/vendor/unsafe-libopus/src/silk/float/find_pitch_lags_FLP.rs new file mode 100644 index 00000000..00b7823d --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/find_pitch_lags_FLP.rs @@ -0,0 +1,125 @@ +pub mod tuning_parameters_h { + pub const FIND_PITCH_WHITE_NOISE_FRACTION: f32 = 1e-3f32; + pub const FIND_PITCH_BANDWIDTH_EXPANSION: f32 = 0.99f32; +} +pub use self::tuning_parameters_h::{ + FIND_PITCH_BANDWIDTH_EXPANSION, FIND_PITCH_WHITE_NOISE_FRACTION, +}; +use crate::externs::{memcpy, memset}; +use crate::silk::define::{TYPE_NO_VOICE_ACTIVITY, TYPE_UNVOICED, TYPE_VOICED}; +use crate::silk::float::apply_sine_window_FLP::silk_apply_sine_window_FLP; +use crate::silk::float::autocorrelation_FLP::silk_autocorrelation_FLP; +use crate::silk::float::bwexpander_FLP::silk_bwexpander_FLP; +use crate::silk::float::k2a_FLP::silk_k2a_FLP; +use crate::silk::float::pitch_analysis_core_FLP::silk_pitch_analysis_core_FLP; +use crate::silk::float::schur_FLP::silk_schur_FLP; +use crate::silk::float::structs_FLP::{silk_encoder_control_FLP, silk_encoder_state_FLP}; +use crate::silk::float::LPC_analysis_filter_FLP::silk_LPC_analysis_filter_FLP; + +pub unsafe fn silk_find_pitch_lags_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + res: *mut f32, + x: *const f32, + arch: i32, +) { + let mut buf_len: i32 = 0; + let mut thrhld: f32 = 0.; + let mut res_nrg: f32 = 0.; + let mut x_buf_ptr: *const f32 = 0 as *const f32; + let mut x_buf: *const f32 = 0 as *const f32; + let mut auto_corr: [f32; 17] = [0.; 17]; + let mut A: [f32; 16] = [0.; 16]; + let mut refl_coef: [f32; 16] = [0.; 16]; + let mut Wsig: [f32; 384] = [0.; 384]; + let mut Wsig_ptr: *mut f32 = 0 as *mut f32; + buf_len = (*psEnc).sCmn.la_pitch + (*psEnc).sCmn.frame_length + (*psEnc).sCmn.ltp_mem_length; + assert!(buf_len >= (*psEnc).sCmn.pitch_LPC_win_length); + x_buf = x.offset(-((*psEnc).sCmn.ltp_mem_length as isize)); + x_buf_ptr = x_buf + .offset(buf_len as isize) + .offset(-((*psEnc).sCmn.pitch_LPC_win_length as isize)); + Wsig_ptr = Wsig.as_mut_ptr(); + silk_apply_sine_window_FLP(Wsig_ptr, x_buf_ptr, 1, (*psEnc).sCmn.la_pitch); + Wsig_ptr = Wsig_ptr.offset((*psEnc).sCmn.la_pitch as isize); + x_buf_ptr = x_buf_ptr.offset((*psEnc).sCmn.la_pitch as isize); + memcpy( + Wsig_ptr as *mut core::ffi::c_void, + x_buf_ptr as *const core::ffi::c_void, + (((*psEnc).sCmn.pitch_LPC_win_length - ((*psEnc).sCmn.la_pitch << 1)) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + Wsig_ptr = Wsig_ptr + .offset(((*psEnc).sCmn.pitch_LPC_win_length - ((*psEnc).sCmn.la_pitch << 1)) as isize); + x_buf_ptr = x_buf_ptr + .offset(((*psEnc).sCmn.pitch_LPC_win_length - ((*psEnc).sCmn.la_pitch << 1)) as isize); + silk_apply_sine_window_FLP(Wsig_ptr, x_buf_ptr, 2, (*psEnc).sCmn.la_pitch); + silk_autocorrelation_FLP( + auto_corr.as_mut_ptr(), + Wsig.as_mut_ptr(), + (*psEnc).sCmn.pitch_LPC_win_length, + (*psEnc).sCmn.pitchEstimationLPCOrder + 1, + ); + auto_corr[0 as usize] += auto_corr[0 as usize] * FIND_PITCH_WHITE_NOISE_FRACTION + 1 as f32; + res_nrg = silk_schur_FLP( + refl_coef.as_mut_ptr(), + auto_corr.as_mut_ptr() as *const f32, + (*psEnc).sCmn.pitchEstimationLPCOrder, + ); + (*psEncCtrl).predGain = + auto_corr[0 as usize] / (if res_nrg > 1.0f32 { res_nrg } else { 1.0f32 }); + silk_k2a_FLP( + A.as_mut_ptr(), + refl_coef.as_mut_ptr(), + (*psEnc).sCmn.pitchEstimationLPCOrder, + ); + silk_bwexpander_FLP( + A.as_mut_ptr(), + (*psEnc).sCmn.pitchEstimationLPCOrder, + FIND_PITCH_BANDWIDTH_EXPANSION, + ); + silk_LPC_analysis_filter_FLP( + res, + A.as_mut_ptr() as *const f32, + x_buf, + buf_len, + (*psEnc).sCmn.pitchEstimationLPCOrder, + ); + if (*psEnc).sCmn.indices.signalType as i32 != TYPE_NO_VOICE_ACTIVITY + && (*psEnc).sCmn.first_frame_after_reset == 0 + { + thrhld = 0.6f32; + thrhld -= 0.004f32 * (*psEnc).sCmn.pitchEstimationLPCOrder as f32; + thrhld -= 0.1f32 * (*psEnc).sCmn.speech_activity_Q8 as f32 * (1.0f32 / 256.0f32); + thrhld -= 0.15f32 * ((*psEnc).sCmn.prevSignalType as i32 >> 1) as f32; + thrhld -= 0.1f32 * (*psEnc).sCmn.input_tilt_Q15 as f32 * (1.0f32 / 32768.0f32); + if silk_pitch_analysis_core_FLP( + res as *const f32, + ((*psEncCtrl).pitchL).as_mut_ptr(), + &mut (*psEnc).sCmn.indices.lagIndex, + &mut (*psEnc).sCmn.indices.contourIndex, + &mut (*psEnc).LTPCorr, + (*psEnc).sCmn.prevLag, + (*psEnc).sCmn.pitchEstimationThreshold_Q16 as f32 / 65536.0f32, + thrhld, + (*psEnc).sCmn.fs_kHz, + (*psEnc).sCmn.pitchEstimationComplexity, + (*psEnc).sCmn.nb_subfr, + arch, + ) == 0 + { + (*psEnc).sCmn.indices.signalType = TYPE_VOICED as i8; + } else { + (*psEnc).sCmn.indices.signalType = TYPE_UNVOICED as i8; + } + } else { + memset( + ((*psEncCtrl).pitchL).as_mut_ptr() as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::<[i32; 4]>() as u64, + ); + (*psEnc).sCmn.indices.lagIndex = 0; + (*psEnc).sCmn.indices.contourIndex = 0; + (*psEnc).LTPCorr = 0 as f32; + }; +} diff --git a/vendor/unsafe-libopus/src/silk/float/find_pred_coefs_FLP.rs b/vendor/unsafe-libopus/src/silk/float/find_pred_coefs_FLP.rs new file mode 100644 index 00000000..9b5c298d --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/find_pred_coefs_FLP.rs @@ -0,0 +1,129 @@ +use crate::externs::{memcpy, memset}; +use crate::silk::define::{ + MAX_PREDICTION_POWER_GAIN, MAX_PREDICTION_POWER_GAIN_AFTER_RESET, TYPE_VOICED, +}; +use crate::silk::float::find_LPC_FLP::silk_find_LPC_FLP; +use crate::silk::float::find_LTP_FLP::silk_find_LTP_FLP; +use crate::silk::float::residual_energy_FLP::silk_residual_energy_FLP; +use crate::silk::float::scale_copy_vector_FLP::silk_scale_copy_vector_FLP; +use crate::silk::float::structs_FLP::{silk_encoder_control_FLP, silk_encoder_state_FLP}; +use crate::silk::float::wrappers_FLP::{silk_process_NLSFs_FLP, silk_quant_LTP_gains_FLP}; +use crate::silk::float::LTP_analysis_filter_FLP::silk_LTP_analysis_filter_FLP; +use crate::silk::float::LTP_scale_ctrl_FLP::silk_LTP_scale_ctrl_FLP; +use crate::silk::mathops::silk_exp2; + +pub unsafe fn silk_find_pred_coefs_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + res_pitch: *const f32, + x: *const f32, + condCoding: i32, +) { + let mut i: i32 = 0; + let mut XXLTP: [f32; 100] = [0.; 100]; + let mut xXLTP: [f32; 20] = [0.; 20]; + let mut invGains: [f32; 4] = [0.; 4]; + let mut NLSF_Q15: [i16; 16] = [0; 16]; + let mut x_ptr: *const f32 = 0 as *const f32; + let mut x_pre_ptr: *mut f32 = 0 as *mut f32; + let mut LPC_in_pre: [f32; 384] = [0.; 384]; + let mut minInvGain: f32 = 0.; + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + invGains[i as usize] = 1.0f32 / (*psEncCtrl).Gains[i as usize]; + i += 1; + } + if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + assert!( + (*psEnc).sCmn.ltp_mem_length - (*psEnc).sCmn.predictLPCOrder + >= (*psEncCtrl).pitchL[0 as usize] + 5 / 2 + ); + silk_find_LTP_FLP( + XXLTP.as_mut_ptr(), + xXLTP.as_mut_ptr(), + res_pitch, + ((*psEncCtrl).pitchL).as_mut_ptr() as *const i32, + (*psEnc).sCmn.subfr_length, + (*psEnc).sCmn.nb_subfr, + ); + silk_quant_LTP_gains_FLP( + ((*psEncCtrl).LTPCoef).as_mut_ptr(), + ((*psEnc).sCmn.indices.LTPIndex).as_mut_ptr(), + &mut (*psEnc).sCmn.indices.PERIndex, + &mut (*psEnc).sCmn.sum_log_gain_Q7, + &mut (*psEncCtrl).LTPredCodGain, + XXLTP.as_mut_ptr() as *const f32, + xXLTP.as_mut_ptr() as *const f32, + (*psEnc).sCmn.subfr_length, + (*psEnc).sCmn.nb_subfr, + (*psEnc).sCmn.arch, + ); + silk_LTP_scale_ctrl_FLP(psEnc, psEncCtrl, condCoding); + silk_LTP_analysis_filter_FLP( + LPC_in_pre.as_mut_ptr(), + x.offset(-((*psEnc).sCmn.predictLPCOrder as isize)), + ((*psEncCtrl).LTPCoef).as_mut_ptr() as *const f32, + ((*psEncCtrl).pitchL).as_mut_ptr() as *const i32, + invGains.as_mut_ptr() as *const f32, + (*psEnc).sCmn.subfr_length, + (*psEnc).sCmn.nb_subfr, + (*psEnc).sCmn.predictLPCOrder, + ); + } else { + x_ptr = x.offset(-((*psEnc).sCmn.predictLPCOrder as isize)); + x_pre_ptr = LPC_in_pre.as_mut_ptr(); + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + silk_scale_copy_vector_FLP( + x_pre_ptr, + x_ptr, + invGains[i as usize], + (*psEnc).sCmn.subfr_length + (*psEnc).sCmn.predictLPCOrder, + ); + x_pre_ptr = x_pre_ptr + .offset(((*psEnc).sCmn.subfr_length + (*psEnc).sCmn.predictLPCOrder) as isize); + x_ptr = x_ptr.offset((*psEnc).sCmn.subfr_length as isize); + i += 1; + } + memset( + ((*psEncCtrl).LTPCoef).as_mut_ptr() as *mut core::ffi::c_void, + 0, + (((*psEnc).sCmn.nb_subfr * 5) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psEncCtrl).LTPredCodGain = 0.0f32; + (*psEnc).sCmn.sum_log_gain_Q7 = 0; + } + if (*psEnc).sCmn.first_frame_after_reset != 0 { + minInvGain = 1.0f32 / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; + } else { + minInvGain = silk_exp2((*psEncCtrl).LTPredCodGain / 3.0) / MAX_PREDICTION_POWER_GAIN; + minInvGain /= 0.25f32 + 0.75f32 * (*psEncCtrl).coding_quality; + } + silk_find_LPC_FLP( + &mut (*psEnc).sCmn, + NLSF_Q15.as_mut_ptr(), + LPC_in_pre.as_mut_ptr() as *const f32, + minInvGain, + ); + silk_process_NLSFs_FLP( + &mut (*psEnc).sCmn, + ((*psEncCtrl).PredCoef).as_mut_ptr(), + NLSF_Q15.as_mut_ptr(), + ((*psEnc).sCmn.prev_NLSFq_Q15).as_mut_ptr() as *const i16, + ); + silk_residual_energy_FLP( + ((*psEncCtrl).ResNrg).as_mut_ptr(), + LPC_in_pre.as_mut_ptr() as *const f32, + ((*psEncCtrl).PredCoef).as_mut_ptr(), + ((*psEncCtrl).Gains).as_mut_ptr() as *const f32, + (*psEnc).sCmn.subfr_length, + (*psEnc).sCmn.nb_subfr, + (*psEnc).sCmn.predictLPCOrder, + ); + memcpy( + ((*psEnc).sCmn.prev_NLSFq_Q15).as_mut_ptr() as *mut core::ffi::c_void, + NLSF_Q15.as_mut_ptr() as *const core::ffi::c_void, + ::core::mem::size_of::<[i16; 16]>() as u64, + ); +} diff --git a/vendor/unsafe-libopus/src/silk/float/inner_product_FLP.rs b/vendor/unsafe-libopus/src/silk/float/inner_product_FLP.rs new file mode 100644 index 00000000..b2643e9f --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/inner_product_FLP.rs @@ -0,0 +1,18 @@ +pub unsafe fn silk_inner_product_FLP(data1: *const f32, data2: *const f32, dataSize: i32) -> f64 { + let mut i: i32 = 0; + let mut result: f64 = 0.; + result = 0.0f64; + i = 0; + while i < dataSize - 3 { + result += *data1.offset((i + 0) as isize) as f64 * *data2.offset((i + 0) as isize) as f64 + + *data1.offset((i + 1) as isize) as f64 * *data2.offset((i + 1) as isize) as f64 + + *data1.offset((i + 2) as isize) as f64 * *data2.offset((i + 2) as isize) as f64 + + *data1.offset((i + 3) as isize) as f64 * *data2.offset((i + 3) as isize) as f64; + i += 4; + } + while i < dataSize { + result += *data1.offset(i as isize) as f64 * *data2.offset(i as isize) as f64; + i += 1; + } + return result; +} diff --git a/vendor/unsafe-libopus/src/silk/float/k2a_FLP.rs b/vendor/unsafe-libopus/src/silk/float/k2a_FLP.rs new file mode 100644 index 00000000..389a2039 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/k2a_FLP.rs @@ -0,0 +1,21 @@ +pub unsafe fn silk_k2a_FLP(A: *mut f32, rc: *const f32, order: i32) { + let mut k: i32 = 0; + let mut n: i32 = 0; + let mut rck: f32 = 0.; + let mut tmp1: f32 = 0.; + let mut tmp2: f32 = 0.; + k = 0; + while k < order { + rck = *rc.offset(k as isize); + n = 0; + while n < k + 1 >> 1 { + tmp1 = *A.offset(n as isize); + tmp2 = *A.offset((k - n - 1) as isize); + *A.offset(n as isize) = tmp1 + tmp2 * rck; + *A.offset((k - n - 1) as isize) = tmp2 + tmp1 * rck; + n += 1; + } + *A.offset(k as isize) = -rck; + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/noise_shape_analysis_FLP.rs b/vendor/unsafe-libopus/src/silk/float/noise_shape_analysis_FLP.rs new file mode 100644 index 00000000..c907efcf --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/noise_shape_analysis_FLP.rs @@ -0,0 +1,378 @@ +pub mod SigProc_FLP_h { + #[inline] + pub unsafe fn silk_sigmoid(x: f32) -> f32 { + return (1.0f64 / (1.0f64 + (-x as f64).exp())) as f32; + } + #[inline] + pub unsafe fn silk_log2(x: f64) -> f32 { + return (3.32192809488736f64 * x.log10()) as f32; + } +} +pub mod tuning_parameters_h { + pub const FIND_PITCH_WHITE_NOISE_FRACTION: f32 = 1e-3f32; + pub const BG_SNR_DECR_dB: f32 = 2.0f32; + pub const HARM_SNR_INCR_dB: f32 = 2.0f32; + pub const ENERGY_VARIATION_THRESHOLD_QNT_OFFSET: f32 = 0.6f32; + pub const SHAPE_WHITE_NOISE_FRACTION: f32 = 3e-5f32; + pub const BANDWIDTH_EXPANSION: f32 = 0.94f32; + pub const HARMONIC_SHAPING: f32 = 0.3f32; + pub const HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING: f32 = 0.2f32; + pub const HP_NOISE_COEF: f32 = 0.25f32; + pub const HARM_HP_NOISE_COEF: f32 = 0.35f32; + pub const LOW_FREQ_SHAPING: f32 = 4.0f32; + pub const LOW_QUALITY_LOW_FREQ_SHAPING_DECR: f32 = 0.5f32; + pub const SUBFR_SMTH_COEF: f32 = 0.4f32; +} + +pub use self::tuning_parameters_h::{ + BG_SNR_DECR_dB, HARM_SNR_INCR_dB, BANDWIDTH_EXPANSION, ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, + FIND_PITCH_WHITE_NOISE_FRACTION, HARMONIC_SHAPING, HARM_HP_NOISE_COEF, + HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, HP_NOISE_COEF, LOW_FREQ_SHAPING, + LOW_QUALITY_LOW_FREQ_SHAPING_DECR, SHAPE_WHITE_NOISE_FRACTION, SUBFR_SMTH_COEF, +}; +use crate::celt::mathops::celt_sqrt; +use crate::silk::define::{MAX_SHAPE_LPC_ORDER, MIN_QGAIN_DB, TYPE_VOICED, USE_HARM_SHAPING}; +use crate::silk::float::structs_FLP::{ + silk_encoder_control_FLP, silk_encoder_state_FLP, silk_shape_state_FLP, +}; + +pub use self::SigProc_FLP_h::{silk_log2, silk_sigmoid}; +use crate::externs::memcpy; +use crate::silk::float::apply_sine_window_FLP::silk_apply_sine_window_FLP; +use crate::silk::float::autocorrelation_FLP::silk_autocorrelation_FLP; +use crate::silk::float::bwexpander_FLP::silk_bwexpander_FLP; +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::k2a_FLP::silk_k2a_FLP; +use crate::silk::float::schur_FLP::silk_schur_FLP; +use crate::silk::float::warped_autocorrelation_FLP::silk_warped_autocorrelation_FLP; +use crate::silk::mathops::silk_exp2; + +#[inline] +unsafe fn warped_gain(coefs: *const f32, mut lambda: f32, order: i32) -> f32 { + let mut i: i32 = 0; + let mut gain: f32 = 0.; + lambda = -lambda; + gain = *coefs.offset((order - 1) as isize); + i = order - 2; + while i >= 0 { + gain = lambda * gain + *coefs.offset(i as isize); + i -= 1; + } + return 1.0f32 / (1.0f32 - lambda * gain); +} +#[inline] +unsafe fn warped_true2monic_coefs(coefs: *mut f32, lambda: f32, limit: f32, order: i32) { + let mut i: i32 = 0; + let mut iter: i32 = 0; + let mut ind: i32 = 0; + let mut tmp: f32 = 0.; + let mut maxabs: f32 = 0.; + let mut chirp: f32 = 0.; + let mut gain: f32 = 0.; + i = order - 1; + while i > 0 { + *coefs.offset((i - 1) as isize) -= lambda * *coefs.offset(i as isize); + i -= 1; + } + gain = (1.0f32 - lambda * lambda) / (1.0f32 + lambda * *coefs.offset(0 as isize)); + i = 0; + while i < order { + *coefs.offset(i as isize) *= gain; + i += 1; + } + iter = 0; + while iter < 10 { + maxabs = -1.0f32; + i = 0; + while i < order { + tmp = (*coefs.offset(i as isize)).abs(); + if tmp > maxabs { + maxabs = tmp; + ind = i; + } + i += 1; + } + if maxabs <= limit { + return; + } + i = 1; + while i < order { + *coefs.offset((i - 1) as isize) += lambda * *coefs.offset(i as isize); + i += 1; + } + gain = 1.0f32 / gain; + i = 0; + while i < order { + *coefs.offset(i as isize) *= gain; + i += 1; + } + chirp = 0.99f32 + - (0.8f32 + 0.1f32 * iter as f32) * (maxabs - limit) / (maxabs * (ind + 1) as f32); + silk_bwexpander_FLP(coefs, order, chirp); + i = order - 1; + while i > 0 { + *coefs.offset((i - 1) as isize) -= lambda * *coefs.offset(i as isize); + i -= 1; + } + gain = (1.0f32 - lambda * lambda) / (1.0f32 + lambda * *coefs.offset(0 as isize)); + i = 0; + while i < order { + *coefs.offset(i as isize) *= gain; + i += 1; + } + iter += 1; + } +} +#[inline] +unsafe fn limit_coefs(coefs: *mut f32, limit: f32, order: i32) { + let mut i: i32 = 0; + let mut iter: i32 = 0; + let mut ind: i32 = 0; + let mut tmp: f32 = 0.; + let mut maxabs: f32 = 0.; + let mut chirp: f32 = 0.; + iter = 0; + while iter < 10 { + maxabs = -1.0f32; + i = 0; + while i < order { + tmp = (*coefs.offset(i as isize)).abs(); + if tmp > maxabs { + maxabs = tmp; + ind = i; + } + i += 1; + } + if maxabs <= limit { + return; + } + chirp = 0.99f32 + - (0.8f32 + 0.1f32 * iter as f32) * (maxabs - limit) / (maxabs * (ind + 1) as f32); + silk_bwexpander_FLP(coefs, order, chirp); + iter += 1; + } +} +pub unsafe fn silk_noise_shape_analysis_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + pitch_res: *const f32, + x: *const f32, +) { + let psShapeSt: *mut silk_shape_state_FLP = &mut (*psEnc).sShape; + let mut k: i32 = 0; + let mut nSamples: i32 = 0; + let mut nSegs: i32 = 0; + let mut SNR_adj_dB: f32 = 0.; + let mut HarmShapeGain: f32 = 0.; + let mut Tilt: f32 = 0.; + let mut nrg: f32 = 0.; + let mut log_energy: f32 = 0.; + let mut log_energy_prev: f32 = 0.; + let mut energy_variation: f32 = 0.; + let mut BWExp: f32 = 0.; + let mut gain_mult: f32 = 0.; + let mut gain_add: f32 = 0.; + let mut strength: f32 = 0.; + let mut b: f32 = 0.; + let mut warping: f32 = 0.; + let mut x_windowed: [f32; 240] = [0.; 240]; + let mut auto_corr: [f32; 25] = [0.; 25]; + let mut rc: [f32; 25] = [0.; 25]; + let mut x_ptr: *const f32 = 0 as *const f32; + let mut pitch_res_ptr: *const f32 = 0 as *const f32; + x_ptr = x.offset(-((*psEnc).sCmn.la_shape as isize)); + SNR_adj_dB = (*psEnc).sCmn.SNR_dB_Q7 as f32 * (1 as f32 / 128.0f32); + (*psEncCtrl).input_quality = 0.5f32 + * ((*psEnc).sCmn.input_quality_bands_Q15[0 as usize] + + (*psEnc).sCmn.input_quality_bands_Q15[1 as usize]) as f32 + * (1.0f32 / 32768.0f32); + (*psEncCtrl).coding_quality = silk_sigmoid(0.25f32 * (SNR_adj_dB - 20.0f32)); + if (*psEnc).sCmn.useCBR == 0 { + b = 1.0f32 - (*psEnc).sCmn.speech_activity_Q8 as f32 * (1.0f32 / 256.0f32); + SNR_adj_dB -= BG_SNR_DECR_dB + * (*psEncCtrl).coding_quality + * (0.5f32 + 0.5f32 * (*psEncCtrl).input_quality) + * b + * b; + } + if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + SNR_adj_dB += HARM_SNR_INCR_dB * (*psEnc).LTPCorr; + } else { + SNR_adj_dB += (-0.4f32 * (*psEnc).sCmn.SNR_dB_Q7 as f32 * (1 as f32 / 128.0f32) + 6.0f32) + * (1.0f32 - (*psEncCtrl).input_quality); + } + if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + (*psEnc).sCmn.indices.quantOffsetType = 0; + } else { + nSamples = 2 * (*psEnc).sCmn.fs_kHz; + energy_variation = 0.0f32; + log_energy_prev = 0.0f32; + pitch_res_ptr = pitch_res; + nSegs = 5 * (*psEnc).sCmn.nb_subfr as i16 as i32 / 2; + k = 0; + while k < nSegs { + nrg = nSamples as f32 + silk_energy_FLP(pitch_res_ptr, nSamples) as f32; + log_energy = silk_log2(nrg as f64); + if k > 0 { + energy_variation += (log_energy - log_energy_prev).abs(); + } + log_energy_prev = log_energy; + pitch_res_ptr = pitch_res_ptr.offset(nSamples as isize); + k += 1; + } + if energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs - 1) as f32 { + (*psEnc).sCmn.indices.quantOffsetType = 0; + } else { + (*psEnc).sCmn.indices.quantOffsetType = 1; + } + } + strength = FIND_PITCH_WHITE_NOISE_FRACTION * (*psEncCtrl).predGain; + BWExp = BANDWIDTH_EXPANSION / (1.0f32 + strength * strength); + warping = (*psEnc).sCmn.warping_Q16 as f32 / 65536.0f32 + 0.01f32 * (*psEncCtrl).coding_quality; + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + let mut shift: i32 = 0; + let mut slope_part: i32 = 0; + let mut flat_part: i32 = 0; + flat_part = (*psEnc).sCmn.fs_kHz * 3; + slope_part = ((*psEnc).sCmn.shapeWinLength - flat_part) / 2; + silk_apply_sine_window_FLP(x_windowed.as_mut_ptr(), x_ptr, 1, slope_part); + shift = slope_part; + memcpy( + x_windowed.as_mut_ptr().offset(shift as isize) as *mut core::ffi::c_void, + x_ptr.offset(shift as isize) as *const core::ffi::c_void, + (flat_part as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + shift += flat_part; + silk_apply_sine_window_FLP( + x_windowed.as_mut_ptr().offset(shift as isize), + x_ptr.offset(shift as isize), + 2, + slope_part, + ); + x_ptr = x_ptr.offset((*psEnc).sCmn.subfr_length as isize); + if (*psEnc).sCmn.warping_Q16 > 0 { + silk_warped_autocorrelation_FLP( + auto_corr.as_mut_ptr(), + x_windowed.as_mut_ptr(), + warping, + (*psEnc).sCmn.shapeWinLength, + (*psEnc).sCmn.shapingLPCOrder, + ); + } else { + silk_autocorrelation_FLP( + auto_corr.as_mut_ptr(), + x_windowed.as_mut_ptr(), + (*psEnc).sCmn.shapeWinLength, + (*psEnc).sCmn.shapingLPCOrder + 1, + ); + } + auto_corr[0 as usize] += auto_corr[0 as usize] * SHAPE_WHITE_NOISE_FRACTION + 1.0f32; + nrg = silk_schur_FLP( + rc.as_mut_ptr(), + auto_corr.as_mut_ptr() as *const f32, + (*psEnc).sCmn.shapingLPCOrder, + ); + silk_k2a_FLP( + &mut *((*psEncCtrl).AR) + .as_mut_ptr() + .offset((k * MAX_SHAPE_LPC_ORDER) as isize), + rc.as_mut_ptr(), + (*psEnc).sCmn.shapingLPCOrder, + ); + (*psEncCtrl).Gains[k as usize] = celt_sqrt(nrg); + if (*psEnc).sCmn.warping_Q16 > 0 { + (*psEncCtrl).Gains[k as usize] *= warped_gain( + &mut *((*psEncCtrl).AR) + .as_mut_ptr() + .offset((k * MAX_SHAPE_LPC_ORDER) as isize), + warping, + (*psEnc).sCmn.shapingLPCOrder, + ); + } + silk_bwexpander_FLP( + &mut *((*psEncCtrl).AR) + .as_mut_ptr() + .offset((k * MAX_SHAPE_LPC_ORDER) as isize), + (*psEnc).sCmn.shapingLPCOrder, + BWExp, + ); + if (*psEnc).sCmn.warping_Q16 > 0 { + warped_true2monic_coefs( + &mut *((*psEncCtrl).AR) + .as_mut_ptr() + .offset((k * MAX_SHAPE_LPC_ORDER) as isize), + warping, + 3.999f32, + (*psEnc).sCmn.shapingLPCOrder, + ); + } else { + limit_coefs( + &mut *((*psEncCtrl).AR) + .as_mut_ptr() + .offset((k * MAX_SHAPE_LPC_ORDER) as isize), + 3.999f32, + (*psEnc).sCmn.shapingLPCOrder, + ); + } + k += 1; + } + gain_mult = silk_exp2(-0.16f32 * SNR_adj_dB); + gain_add = silk_exp2(0.16f32 * MIN_QGAIN_DB as f32); + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + (*psEncCtrl).Gains[k as usize] *= gain_mult; + (*psEncCtrl).Gains[k as usize] += gain_add; + k += 1; + } + strength = LOW_FREQ_SHAPING + * (1.0f32 + + LOW_QUALITY_LOW_FREQ_SHAPING_DECR + * ((*psEnc).sCmn.input_quality_bands_Q15[0 as usize] as f32 + * (1.0f32 / 32768.0f32) + - 1.0f32)); + strength *= (*psEnc).sCmn.speech_activity_Q8 as f32 * (1.0f32 / 256.0f32); + if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + b = 0.2f32 / (*psEnc).sCmn.fs_kHz as f32 + + 3.0f32 / (*psEncCtrl).pitchL[k as usize] as f32; + (*psEncCtrl).LF_MA_shp[k as usize] = -1.0f32 + b; + (*psEncCtrl).LF_AR_shp[k as usize] = 1.0f32 - b - b * strength; + k += 1; + } + Tilt = -HP_NOISE_COEF + - (1 as f32 - HP_NOISE_COEF) + * HARM_HP_NOISE_COEF + * (*psEnc).sCmn.speech_activity_Q8 as f32 + * (1.0f32 / 256.0f32); + } else { + b = 1.3f32 / (*psEnc).sCmn.fs_kHz as f32; + (*psEncCtrl).LF_MA_shp[0 as usize] = -1.0f32 + b; + (*psEncCtrl).LF_AR_shp[0 as usize] = 1.0f32 - b - b * strength * 0.6f32; + k = 1; + while k < (*psEnc).sCmn.nb_subfr { + (*psEncCtrl).LF_MA_shp[k as usize] = (*psEncCtrl).LF_MA_shp[0 as usize]; + (*psEncCtrl).LF_AR_shp[k as usize] = (*psEncCtrl).LF_AR_shp[0 as usize]; + k += 1; + } + Tilt = -HP_NOISE_COEF; + } + if USE_HARM_SHAPING != 0 && (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + HarmShapeGain = HARMONIC_SHAPING; + HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING + * (1.0f32 - (1.0f32 - (*psEncCtrl).coding_quality) * (*psEncCtrl).input_quality); + HarmShapeGain *= celt_sqrt((*psEnc).LTPCorr); + } else { + HarmShapeGain = 0.0f32; + } + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + (*psShapeSt).HarmShapeGain_smth += + SUBFR_SMTH_COEF * (HarmShapeGain - (*psShapeSt).HarmShapeGain_smth); + (*psEncCtrl).HarmShapeGain[k as usize] = (*psShapeSt).HarmShapeGain_smth; + (*psShapeSt).Tilt_smth += SUBFR_SMTH_COEF * (Tilt - (*psShapeSt).Tilt_smth); + (*psEncCtrl).Tilt[k as usize] = (*psShapeSt).Tilt_smth; + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/pitch_analysis_core_FLP.rs b/vendor/unsafe-libopus/src/silk/float/pitch_analysis_core_FLP.rs new file mode 100644 index 00000000..65dbe0c6 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/pitch_analysis_core_FLP.rs @@ -0,0 +1,776 @@ +pub mod arch_h { + pub type opus_val32 = f32; +} +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub mod SigProc_FLP_h { + #[inline] + pub unsafe fn silk_float2short_array(out: *mut i16, in_0: *const f32, length: i32) { + let mut k: i32 = 0; + k = length - 1; + while k >= 0 { + *out.offset(k as isize) = (if float2int(*in_0.offset(k as isize)) > silk_int16_MAX { + silk_int16_MAX + } else if float2int(*in_0.offset(k as isize)) < silk_int16_MIN { + silk_int16_MIN + } else { + float2int(*in_0.offset(k as isize)) + }) as i16; + k -= 1; + } + } + #[inline] + pub unsafe fn silk_short2float_array(out: *mut f32, in_0: *const i16, length: i32) { + let mut k: i32 = 0; + k = length - 1; + while k >= 0 { + *out.offset(k as isize) = *in_0.offset(k as isize) as f32; + k -= 1; + } + } + #[inline] + pub unsafe fn silk_log2(x: f64) -> f32 { + return (3.32192809488736f64 * x.log10()) as f32; + } + use super::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + use crate::celt::float_cast::float2int; +} +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int16_MIN: i32 = i16::MIN as i32; +} + +use self::arch_h::opus_val32; +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +pub use self::SigProc_FLP_h::{silk_float2short_array, silk_log2, silk_short2float_array}; +use crate::celt::pitch::celt_pitch_xcorr_c; +use crate::externs::memset; +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::inner_product_FLP::silk_inner_product_FLP; +use crate::silk::float::sort_FLP::silk_insertion_sort_decreasing_FLP; +use crate::silk::pitch_est_tables::{ + silk_CB_lags_stage2, silk_CB_lags_stage2_10_ms, silk_CB_lags_stage3, silk_CB_lags_stage3_10_ms, + silk_Lag_range_stage3, silk_Lag_range_stage3_10_ms, silk_nb_cbk_searchs_stage3, + PE_FLATCONTOUR_BIAS, PE_LTP_MEM_LENGTH_MS, PE_MAX_LAG_MS, PE_MAX_NB_SUBFR, PE_MIN_LAG_MS, + PE_NB_CBKS_STAGE2, PE_NB_CBKS_STAGE2_10MS, PE_NB_CBKS_STAGE2_EXT, PE_NB_CBKS_STAGE3_10MS, + PE_NB_CBKS_STAGE3_MAX, PE_NB_STAGE3_LAGS, PE_PREVLAG_BIAS, PE_SHORTLAG_BIAS, + PE_SUBFR_LENGTH_MS, SILK_PE_MIN_COMPLEX, +}; +use crate::silk::resampler::{silk_resampler_down2, silk_resampler_down2_3}; +use crate::silk::SigProc_FIX::{silk_max_int, silk_min_int}; +use arrayref::array_mut_ref; + +pub unsafe fn silk_pitch_analysis_core_FLP( + frame: *const f32, + pitch_out: *mut i32, + lagIndex: *mut i16, + contourIndex: *mut i8, + LTPCorr: *mut f32, + mut prevLag: i32, + search_thres1: f32, + search_thres2: f32, + Fs_kHz: i32, + complexity: i32, + nb_subfr: i32, + arch: i32, +) -> i32 { + let mut i: i32 = 0; + let mut k: i32 = 0; + let mut d: i32 = 0; + let mut j: i32 = 0; + let mut frame_8kHz: [f32; 320] = [0.; 320]; + let mut frame_4kHz: [f32; 160] = [0.; 160]; + let mut frame_8_FIX: [i16; 320] = [0; 320]; + let mut frame_4_FIX: [i16; 160] = [0; 160]; + let mut filt_state: [i32; 6] = [0; 6]; + let mut threshold: f32 = 0.; + let mut contour_bias: f32 = 0.; + let mut C: [[f32; 149]; 4] = [[0.; 149]; 4]; + let mut xcorr: [opus_val32; 65] = [0.; 65]; + let mut CC: [f32; 11] = [0.; 11]; + let mut target_ptr: *const f32 = 0 as *const f32; + let mut basis_ptr: *const f32 = 0 as *const f32; + let mut cross_corr: f64 = 0.; + let mut normalizer: f64 = 0.; + let mut energy: f64 = 0.; + let mut energy_tmp: f64 = 0.; + let mut d_srch: [i32; 24] = [0; 24]; + let mut d_comp: [i16; 149] = [0; 149]; + let mut length_d_srch: i32 = 0; + let mut length_d_comp: i32 = 0; + let mut Cmax: f32 = 0.; + let mut CCmax: f32 = 0.; + let mut CCmax_b: f32 = 0.; + let mut CCmax_new_b: f32 = 0.; + let mut CCmax_new: f32 = 0.; + let mut CBimax: i32 = 0; + let mut CBimax_new: i32 = 0; + let mut lag: i32 = 0; + let mut start_lag: i32 = 0; + let mut end_lag: i32 = 0; + let mut lag_new: i32 = 0; + let mut cbk_size: i32 = 0; + let mut lag_log2: f32 = 0.; + let mut prevLag_log2: f32 = 0.; + let mut delta_lag_log2_sqr: f32 = 0.; + let mut energies_st3: [[[f32; 5]; 34]; 4] = [[[0.; 5]; 34]; 4]; + let mut cross_corr_st3: [[[f32; 5]; 34]; 4] = [[[0.; 5]; 34]; 4]; + let mut lag_counter: i32 = 0; + let mut frame_length: i32 = 0; + let mut frame_length_8kHz: i32 = 0; + let mut frame_length_4kHz: i32 = 0; + let mut sf_length: i32 = 0; + let mut sf_length_8kHz: i32 = 0; + let mut sf_length_4kHz: i32 = 0; + let mut min_lag: i32 = 0; + let mut min_lag_8kHz: i32 = 0; + let mut min_lag_4kHz: i32 = 0; + let mut max_lag: i32 = 0; + let mut max_lag_8kHz: i32 = 0; + let mut max_lag_4kHz: i32 = 0; + let mut nb_cbk_search: i32 = 0; + let mut Lag_CB_ptr: *const i8 = 0 as *const i8; + assert!(Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16); + assert!(complexity >= 0); + assert!(complexity <= 2); + frame_length = (PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS) * Fs_kHz; + frame_length_4kHz = (PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS) * 4; + frame_length_8kHz = (PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS) * 8; + sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; + sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; + sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; + min_lag = PE_MIN_LAG_MS * Fs_kHz; + min_lag_4kHz = PE_MIN_LAG_MS * 4; + min_lag_8kHz = PE_MIN_LAG_MS * 8; + max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; + max_lag_4kHz = PE_MAX_LAG_MS * 4; + max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; + if Fs_kHz == 16 { + let mut frame_16_FIX: [i16; 640] = [0; 640]; + silk_float2short_array(frame_16_FIX.as_mut_ptr(), frame, frame_length); + let filt_state = array_mut_ref![filt_state, 0, 2]; + filt_state.fill(0); + silk_resampler_down2( + filt_state, + &mut frame_8_FIX[..frame_length_8kHz as usize], + &frame_16_FIX[..frame_length as usize], + ); + silk_short2float_array( + frame_8kHz.as_mut_ptr(), + frame_8_FIX.as_mut_ptr(), + frame_length_8kHz, + ); + } else if Fs_kHz == 12 { + let mut frame_12_FIX: [i16; 480] = [0; 480]; + silk_float2short_array(frame_12_FIX.as_mut_ptr(), frame, frame_length); + filt_state.fill(0); + silk_resampler_down2_3( + &mut filt_state, + &mut frame_8_FIX[..frame_length_8kHz as usize], + &frame_12_FIX[..frame_length as usize], + ); + silk_short2float_array( + frame_8kHz.as_mut_ptr(), + frame_8_FIX.as_mut_ptr(), + frame_length_8kHz, + ); + } else { + assert!(Fs_kHz == 8); + silk_float2short_array(frame_8_FIX.as_mut_ptr(), frame, frame_length_8kHz); + } + { + let filt_state = array_mut_ref![filt_state, 0, 2]; + filt_state.fill(0); + silk_resampler_down2( + filt_state, + &mut frame_4_FIX[..frame_length_4kHz as usize], + &frame_8_FIX[..frame_length_8kHz as usize], + ); + } + silk_short2float_array( + frame_4kHz.as_mut_ptr(), + frame_4_FIX.as_mut_ptr(), + frame_length_4kHz, + ); + i = frame_length_4kHz - 1; + while i > 0 { + frame_4kHz[i as usize] = (if frame_4kHz[i as usize] as i32 as f32 + + frame_4kHz[(i - 1) as usize] + > silk_int16_MAX as f32 + { + silk_int16_MAX as f32 + } else if frame_4kHz[i as usize] as i32 as f32 + frame_4kHz[(i - 1) as usize] + < silk_int16_MIN as f32 + { + silk_int16_MIN as f32 + } else { + frame_4kHz[i as usize] as i32 as f32 + frame_4kHz[(i - 1) as usize] + }) as i16 as f32; + i -= 1; + } + memset( + C.as_mut_ptr() as *mut core::ffi::c_void, + 0, + (::core::mem::size_of::() as u64) + .wrapping_mul(nb_subfr as u64) + .wrapping_mul(((18 * 16 >> 1) + 5) as u64), + ); + target_ptr = &mut *frame_4kHz + .as_mut_ptr() + .offset(((sf_length_4kHz as u32) << 2) as i32 as isize) as *mut f32; + k = 0; + while k < nb_subfr >> 1 { + assert!(target_ptr >= frame_4kHz.as_mut_ptr() as *const f32); + assert!( + target_ptr.offset(sf_length_8kHz as isize) + <= frame_4kHz.as_mut_ptr().offset(frame_length_4kHz as isize) as *const f32 + ); + basis_ptr = target_ptr.offset(-(min_lag_4kHz as isize)); + assert!(basis_ptr >= frame_4kHz.as_mut_ptr() as *const f32); + assert!( + basis_ptr.offset(sf_length_8kHz as isize) + <= frame_4kHz.as_mut_ptr().offset(frame_length_4kHz as isize) as *const f32 + ); + celt_pitch_xcorr_c( + target_ptr, + target_ptr.offset(-(max_lag_4kHz as isize)), + xcorr.as_mut_ptr(), + sf_length_8kHz, + max_lag_4kHz - min_lag_4kHz + 1, + arch, + ); + cross_corr = xcorr[(max_lag_4kHz - min_lag_4kHz) as usize] as f64; + normalizer = silk_energy_FLP(target_ptr, sf_length_8kHz) + + silk_energy_FLP(basis_ptr, sf_length_8kHz) + + (sf_length_8kHz as f32 * 4000.0f32) as f64; + C[0 as usize][min_lag_4kHz as usize] += (2 as f64 * cross_corr / normalizer) as f32; + d = min_lag_4kHz + 1; + while d <= max_lag_4kHz { + basis_ptr = basis_ptr.offset(-1); + cross_corr = xcorr[(max_lag_4kHz - d) as usize] as f64; + normalizer += *basis_ptr.offset(0 as isize) as f64 + * *basis_ptr.offset(0 as isize) as f64 + - *basis_ptr.offset(sf_length_8kHz as isize) as f64 + * *basis_ptr.offset(sf_length_8kHz as isize) as f64; + C[0 as usize][d as usize] += (2 as f64 * cross_corr / normalizer) as f32; + d += 1; + } + target_ptr = target_ptr.offset(sf_length_8kHz as isize); + k += 1; + } + i = max_lag_4kHz; + while i >= min_lag_4kHz { + C[0 as usize][i as usize] -= C[0 as usize][i as usize] * i as f32 / 4096.0f32; + i -= 1; + } + length_d_srch = 4 + 2 * complexity; + assert!(3 * length_d_srch <= 24); + silk_insertion_sort_decreasing_FLP( + &mut *(*C.as_mut_ptr().offset(0 as isize)) + .as_mut_ptr() + .offset(min_lag_4kHz as isize), + d_srch.as_mut_ptr(), + max_lag_4kHz - min_lag_4kHz + 1, + length_d_srch, + ); + Cmax = C[0 as usize][min_lag_4kHz as usize]; + if Cmax < 0.2f32 { + memset( + pitch_out as *mut core::ffi::c_void, + 0, + (nb_subfr as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + *LTPCorr = 0.0f32; + *lagIndex = 0; + *contourIndex = 0; + return 1; + } + threshold = search_thres1 * Cmax; + i = 0; + while i < length_d_srch { + if C[0 as usize][(min_lag_4kHz + i) as usize] > threshold { + d_srch[i as usize] = (((d_srch[i as usize] + min_lag_4kHz) as u32) << 1) as i32; + i += 1; + } else { + length_d_srch = i; + break; + } + } + assert!(length_d_srch > 0); + i = min_lag_8kHz - 5; + while i < max_lag_8kHz + 5 { + d_comp[i as usize] = 0; + i += 1; + } + i = 0; + while i < length_d_srch { + d_comp[d_srch[i as usize] as usize] = 1; + i += 1; + } + i = max_lag_8kHz + 3; + while i >= min_lag_8kHz { + d_comp[i as usize] = (d_comp[i as usize] as i32 + + (d_comp[(i - 1) as usize] as i32 + d_comp[(i - 2) as usize] as i32)) + as i16; + i -= 1; + } + length_d_srch = 0; + i = min_lag_8kHz; + while i < max_lag_8kHz + 1 { + if d_comp[(i + 1) as usize] as i32 > 0 { + d_srch[length_d_srch as usize] = i; + length_d_srch += 1; + } + i += 1; + } + i = max_lag_8kHz + 3; + while i >= min_lag_8kHz { + d_comp[i as usize] = (d_comp[i as usize] as i32 + + (d_comp[(i - 1) as usize] as i32 + + d_comp[(i - 2) as usize] as i32 + + d_comp[(i - 3) as usize] as i32)) as i16; + i -= 1; + } + length_d_comp = 0; + i = min_lag_8kHz; + while i < max_lag_8kHz + 4 { + if d_comp[i as usize] as i32 > 0 { + d_comp[length_d_comp as usize] = (i - 2) as i16; + length_d_comp += 1; + } + i += 1; + } + memset( + C.as_mut_ptr() as *mut core::ffi::c_void, + 0, + ((4 * ((18 * 16 >> 1) + 5)) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + if Fs_kHz == 8 { + target_ptr = &*frame.offset((PE_LTP_MEM_LENGTH_MS * 8) as isize) as *const f32; + } else { + target_ptr = &mut *frame_8kHz + .as_mut_ptr() + .offset((PE_LTP_MEM_LENGTH_MS * 8) as isize) as *mut f32; + } + k = 0; + while k < nb_subfr { + energy_tmp = silk_energy_FLP(target_ptr, sf_length_8kHz) + 1.0f64; + j = 0; + while j < length_d_comp { + d = d_comp[j as usize] as i32; + basis_ptr = target_ptr.offset(-(d as isize)); + cross_corr = silk_inner_product_FLP(basis_ptr, target_ptr, sf_length_8kHz); + if cross_corr > 0.0f32 as f64 { + energy = silk_energy_FLP(basis_ptr, sf_length_8kHz); + C[k as usize][d as usize] = (2 as f64 * cross_corr / (energy + energy_tmp)) as f32; + } else { + C[k as usize][d as usize] = 0.0f32; + } + j += 1; + } + target_ptr = target_ptr.offset(sf_length_8kHz as isize); + k += 1; + } + CCmax = 0.0f32; + CCmax_b = -1000.0f32; + CBimax = 0; + lag = -1; + if prevLag > 0 { + if Fs_kHz == 12 { + prevLag = ((prevLag as u32) << 1) as i32 / 3; + } else if Fs_kHz == 16 { + prevLag = prevLag >> 1; + } + prevLag_log2 = silk_log2(prevLag as f32 as f64); + } else { + prevLag_log2 = 0 as f32; + } + if nb_subfr == PE_MAX_NB_SUBFR { + cbk_size = PE_NB_CBKS_STAGE2_EXT; + Lag_CB_ptr = &*(*silk_CB_lags_stage2.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + if Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX { + nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; + } else { + nb_cbk_search = PE_NB_CBKS_STAGE2; + } + } else { + cbk_size = PE_NB_CBKS_STAGE2_10MS; + Lag_CB_ptr = &*(*silk_CB_lags_stage2_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; + } + k = 0; + while k < length_d_srch { + d = d_srch[k as usize]; + j = 0; + while j < nb_cbk_search { + CC[j as usize] = 0.0f32; + i = 0; + while i < nb_subfr { + CC[j as usize] += C[i as usize] + [(d + *Lag_CB_ptr.offset((i * cbk_size + j) as isize) as i32) as usize]; + i += 1; + } + j += 1; + } + CCmax_new = -1000.0f32; + CBimax_new = 0; + i = 0; + while i < nb_cbk_search { + if CC[i as usize] > CCmax_new { + CCmax_new = CC[i as usize]; + CBimax_new = i; + } + i += 1; + } + lag_log2 = silk_log2(d as f32 as f64); + CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr as f32 * lag_log2; + if prevLag > 0 { + delta_lag_log2_sqr = lag_log2 - prevLag_log2; + delta_lag_log2_sqr *= delta_lag_log2_sqr; + CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr as f32 * *LTPCorr * delta_lag_log2_sqr + / (delta_lag_log2_sqr + 0.5f32); + } + if CCmax_new_b > CCmax_b && CCmax_new > nb_subfr as f32 * search_thres2 { + CCmax_b = CCmax_new_b; + CCmax = CCmax_new; + lag = d; + CBimax = CBimax_new; + } + k += 1; + } + if lag == -1 { + memset( + pitch_out as *mut core::ffi::c_void, + 0, + 4_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + *LTPCorr = 0.0f32; + *lagIndex = 0; + *contourIndex = 0; + return 1; + } + *LTPCorr = CCmax / nb_subfr as f32; + if Fs_kHz > 8 { + if Fs_kHz == 12 { + lag = if 1 == 1 { + (lag as i16 as i32 * 3 >> 1) + (lag as i16 as i32 * 3 & 1) + } else { + (lag as i16 as i32 * 3 >> 1 - 1) + 1 >> 1 + }; + } else { + lag = ((lag as u32) << 1) as i32; + } + lag = if min_lag > max_lag { + if lag > min_lag { + min_lag + } else if lag < max_lag { + max_lag + } else { + lag + } + } else if lag > max_lag { + max_lag + } else if lag < min_lag { + min_lag + } else { + lag + }; + start_lag = silk_max_int(lag - 2, min_lag); + end_lag = silk_min_int(lag + 2, max_lag); + lag_new = lag; + CBimax = 0; + CCmax = -1000.0f32; + silk_P_Ana_calc_corr_st3( + cross_corr_st3.as_mut_ptr(), + frame, + start_lag, + sf_length, + nb_subfr, + complexity, + arch, + ); + silk_P_Ana_calc_energy_st3( + energies_st3.as_mut_ptr(), + frame, + start_lag, + sf_length, + nb_subfr, + complexity, + ); + lag_counter = 0; + contour_bias = PE_FLATCONTOUR_BIAS / lag as f32; + if nb_subfr == PE_MAX_NB_SUBFR { + nb_cbk_search = silk_nb_cbk_searchs_stage3[complexity as usize] as i32; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + } else { + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + } + target_ptr = &*frame.offset((PE_LTP_MEM_LENGTH_MS * Fs_kHz) as isize) as *const f32; + energy_tmp = silk_energy_FLP(target_ptr, nb_subfr * sf_length) + 1.0f64; + d = start_lag; + while d <= end_lag { + j = 0; + while j < nb_cbk_search { + cross_corr = 0.0f64; + energy = energy_tmp; + k = 0; + while k < nb_subfr { + cross_corr += + cross_corr_st3[k as usize][j as usize][lag_counter as usize] as f64; + energy += energies_st3[k as usize][j as usize][lag_counter as usize] as f64; + k += 1; + } + if cross_corr > 0.0f64 { + CCmax_new = (2 as f64 * cross_corr / energy) as f32; + CCmax_new *= 1.0f32 - contour_bias * j as f32; + } else { + CCmax_new = 0.0f32; + } + if CCmax_new > CCmax + && d + silk_CB_lags_stage3[0 as usize][j as usize] as i32 <= max_lag + { + CCmax = CCmax_new; + lag_new = d; + CBimax = j; + } + j += 1; + } + lag_counter += 1; + d += 1; + } + k = 0; + while k < nb_subfr { + *pitch_out.offset(k as isize) = + lag_new + *Lag_CB_ptr.offset((k * cbk_size + CBimax) as isize) as i32; + *pitch_out.offset(k as isize) = if min_lag > 18 * Fs_kHz { + if *pitch_out.offset(k as isize) > min_lag { + min_lag + } else if *pitch_out.offset(k as isize) < 18 * Fs_kHz { + 18 * Fs_kHz + } else { + *pitch_out.offset(k as isize) + } + } else if *pitch_out.offset(k as isize) > 18 * Fs_kHz { + 18 * Fs_kHz + } else if *pitch_out.offset(k as isize) < min_lag { + min_lag + } else { + *pitch_out.offset(k as isize) + }; + k += 1; + } + *lagIndex = (lag_new - min_lag) as i16; + *contourIndex = CBimax as i8; + } else { + k = 0; + while k < nb_subfr { + *pitch_out.offset(k as isize) = + lag + *Lag_CB_ptr.offset((k * cbk_size + CBimax) as isize) as i32; + *pitch_out.offset(k as isize) = if min_lag_8kHz > 18 * 8 { + if *pitch_out.offset(k as isize) > min_lag_8kHz { + min_lag_8kHz + } else if *pitch_out.offset(k as isize) < 18 * 8 { + 18 * 8 + } else { + *pitch_out.offset(k as isize) + } + } else if *pitch_out.offset(k as isize) > 18 * 8 { + 18 * 8 + } else if *pitch_out.offset(k as isize) < min_lag_8kHz { + min_lag_8kHz + } else { + *pitch_out.offset(k as isize) + }; + k += 1; + } + *lagIndex = (lag - min_lag_8kHz) as i16; + *contourIndex = CBimax as i8; + } + assert!(*lagIndex as i32 >= 0); + return 0; +} +unsafe fn silk_P_Ana_calc_corr_st3( + cross_corr_st3: *mut [[f32; 5]; 34], + frame: *const f32, + start_lag: i32, + sf_length: i32, + nb_subfr: i32, + complexity: i32, + arch: i32, +) { + let mut target_ptr: *const f32 = 0 as *const f32; + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + let mut lag_counter: i32 = 0; + let mut lag_low: i32 = 0; + let mut lag_high: i32 = 0; + let mut nb_cbk_search: i32 = 0; + let mut delta: i32 = 0; + let mut idx: i32 = 0; + let mut cbk_size: i32 = 0; + let mut scratch_mem: [f32; 22] = [0.; 22]; + let mut xcorr: [opus_val32; 22] = [0.; 22]; + let mut Lag_range_ptr: *const i8 = 0 as *const i8; + let mut Lag_CB_ptr: *const i8 = 0 as *const i8; + assert!(complexity >= 0); + assert!(complexity <= 2); + if nb_subfr == PE_MAX_NB_SUBFR { + Lag_range_ptr = &*(*(*silk_Lag_range_stage3.as_ptr().offset(complexity as isize)) + .as_ptr() + .offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + nb_cbk_search = silk_nb_cbk_searchs_stage3[complexity as usize] as i32; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + assert!(nb_subfr == 4 >> 1); + Lag_range_ptr = &*(*silk_Lag_range_stage3_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + target_ptr = &*frame.offset(((sf_length as u32) << 2) as i32 as isize) as *const f32; + k = 0; + while k < nb_subfr { + lag_counter = 0; + lag_low = *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32; + lag_high = *Lag_range_ptr.offset((k * 2 + 1) as isize) as i32; + celt_pitch_xcorr_c( + target_ptr, + target_ptr + .offset(-(start_lag as isize)) + .offset(-(lag_high as isize)), + xcorr.as_mut_ptr(), + sf_length, + lag_high - lag_low + 1, + arch, + ); + j = lag_low; + while j <= lag_high { + scratch_mem[lag_counter as usize] = xcorr[(lag_high - j) as usize]; + lag_counter += 1; + j += 1; + } + delta = *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32; + i = 0; + while i < nb_cbk_search { + idx = *Lag_CB_ptr.offset((k * cbk_size + i) as isize) as i32 - delta; + j = 0; + while j < PE_NB_STAGE3_LAGS { + (*cross_corr_st3.offset(k as isize))[i as usize][j as usize] = + scratch_mem[(idx + j) as usize]; + j += 1; + } + i += 1; + } + target_ptr = target_ptr.offset(sf_length as isize); + k += 1; + } +} +unsafe fn silk_P_Ana_calc_energy_st3( + energies_st3: *mut [[f32; 5]; 34], + frame: *const f32, + start_lag: i32, + sf_length: i32, + nb_subfr: i32, + complexity: i32, +) { + let mut target_ptr: *const f32 = 0 as *const f32; + let mut basis_ptr: *const f32 = 0 as *const f32; + let mut energy: f64 = 0.; + let mut k: i32 = 0; + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut lag_counter: i32 = 0; + let mut nb_cbk_search: i32 = 0; + let mut delta: i32 = 0; + let mut idx: i32 = 0; + let mut cbk_size: i32 = 0; + let mut lag_diff: i32 = 0; + let mut scratch_mem: [f32; 22] = [0.; 22]; + let mut Lag_range_ptr: *const i8 = 0 as *const i8; + let mut Lag_CB_ptr: *const i8 = 0 as *const i8; + assert!(complexity >= 0); + assert!(complexity <= 2); + if nb_subfr == PE_MAX_NB_SUBFR { + Lag_range_ptr = &*(*(*silk_Lag_range_stage3.as_ptr().offset(complexity as isize)) + .as_ptr() + .offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + nb_cbk_search = silk_nb_cbk_searchs_stage3[complexity as usize] as i32; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + assert!(nb_subfr == 4 >> 1); + Lag_range_ptr = &*(*silk_Lag_range_stage3_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize)) + .as_ptr() + .offset(0 as isize) as *const i8; + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + target_ptr = &*frame.offset(((sf_length as u32) << 2) as i32 as isize) as *const f32; + k = 0; + while k < nb_subfr { + lag_counter = 0; + basis_ptr = target_ptr + .offset(-((start_lag + *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32) as isize)); + energy = silk_energy_FLP(basis_ptr, sf_length) + 1e-3f64; + scratch_mem[lag_counter as usize] = energy as f32; + lag_counter += 1; + lag_diff = *Lag_range_ptr.offset((k * 2 + 1) as isize) as i32 + - *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32 + + 1; + i = 1; + while i < lag_diff { + energy -= *basis_ptr.offset((sf_length - i) as isize) as f64 + * *basis_ptr.offset((sf_length - i) as isize) as f64; + energy += *basis_ptr.offset(-i as isize) as f64 * *basis_ptr.offset(-i as isize) as f64; + scratch_mem[lag_counter as usize] = energy as f32; + lag_counter += 1; + i += 1; + } + delta = *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32; + i = 0; + while i < nb_cbk_search { + idx = *Lag_CB_ptr.offset((k * cbk_size + i) as isize) as i32 - delta; + j = 0; + while j < PE_NB_STAGE3_LAGS { + (*energies_st3.offset(k as isize))[i as usize][j as usize] = + scratch_mem[(idx + j) as usize]; + j += 1; + } + i += 1; + } + target_ptr = target_ptr.offset(sf_length as isize); + k += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/process_gains_FLP.rs b/vendor/unsafe-libopus/src/silk/float/process_gains_FLP.rs new file mode 100644 index 00000000..0db87269 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/process_gains_FLP.rs @@ -0,0 +1,102 @@ +pub mod SigProc_FLP_h { + #[inline] + pub unsafe fn silk_sigmoid(x: f32) -> f32 { + return (1.0f64 / (1.0f64 + (-x as f64).exp())) as f32; + } +} +pub mod tuning_parameters_h { + pub const LAMBDA_OFFSET: f32 = 1.2f32; + pub const LAMBDA_SPEECH_ACT: f32 = -0.2f32; + pub const LAMBDA_DELAYED_DECISIONS: f32 = -0.05f32; + pub const LAMBDA_INPUT_QUALITY: f32 = -0.1f32; + pub const LAMBDA_CODING_QUALITY: f32 = -0.2f32; + pub const LAMBDA_QUANT_OFFSET: f32 = 0.8f32; +} + +pub use self::tuning_parameters_h::{ + LAMBDA_CODING_QUALITY, LAMBDA_DELAYED_DECISIONS, LAMBDA_INPUT_QUALITY, LAMBDA_OFFSET, + LAMBDA_QUANT_OFFSET, LAMBDA_SPEECH_ACT, +}; +pub use self::SigProc_FLP_h::silk_sigmoid; +use crate::celt::mathops::celt_sqrt; +use crate::externs::memcpy; +use crate::silk::define::{CODE_CONDITIONALLY, TYPE_VOICED}; +use crate::silk::float::structs_FLP::{ + silk_encoder_control_FLP, silk_encoder_state_FLP, silk_shape_state_FLP, +}; +use crate::silk::gain_quant::silk_gains_quant; +use crate::silk::mathops::silk_exp2; +use crate::silk::tables_other::silk_Quantization_Offsets_Q10; + +pub unsafe fn silk_process_gains_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + condCoding: i32, +) { + let psShapeSt: *mut silk_shape_state_FLP = &mut (*psEnc).sShape; + let mut k: i32 = 0; + let mut pGains_Q16: [i32; 4] = [0; 4]; + let mut s: f32 = 0.; + let mut InvMaxSqrVal: f32 = 0.; + let mut gain: f32 = 0.; + let mut quant_offset: f32 = 0.; + if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + s = 1.0f32 - 0.5f32 * silk_sigmoid(0.25f32 * ((*psEncCtrl).LTPredCodGain - 12.0f32)); + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + (*psEncCtrl).Gains[k as usize] *= s; + k += 1; + } + } + InvMaxSqrVal = silk_exp2(0.33f32 * (21.0f32 - (*psEnc).sCmn.SNR_dB_Q7 as f32 * (1.0 / 128.0))) + / (*psEnc).sCmn.subfr_length as f32; + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + gain = (*psEncCtrl).Gains[k as usize]; + gain = celt_sqrt(gain * gain + (*psEncCtrl).ResNrg[k as usize] * InvMaxSqrVal); + (*psEncCtrl).Gains[k as usize] = if gain < 32767.0f32 { gain } else { 32767.0f32 }; + k += 1; + } + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + pGains_Q16[k as usize] = ((*psEncCtrl).Gains[k as usize] * 65536.0f32) as i32; + k += 1; + } + memcpy( + ((*psEncCtrl).GainsUnq_Q16).as_mut_ptr() as *mut core::ffi::c_void, + pGains_Q16.as_mut_ptr() as *const core::ffi::c_void, + ((*psEnc).sCmn.nb_subfr as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + (*psEncCtrl).lastGainIndexPrev = (*psShapeSt).LastGainIndex; + silk_gains_quant( + ((*psEnc).sCmn.indices.GainsIndices).as_mut_ptr(), + pGains_Q16.as_mut_ptr(), + &mut (*psShapeSt).LastGainIndex, + (condCoding == CODE_CONDITIONALLY) as i32, + (*psEnc).sCmn.nb_subfr, + ); + k = 0; + while k < (*psEnc).sCmn.nb_subfr { + (*psEncCtrl).Gains[k as usize] = pGains_Q16[k as usize] as f32 / 65536.0f32; + k += 1; + } + if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED { + if (*psEncCtrl).LTPredCodGain + (*psEnc).sCmn.input_tilt_Q15 as f32 * (1.0f32 / 32768.0f32) + > 1.0f32 + { + (*psEnc).sCmn.indices.quantOffsetType = 0; + } else { + (*psEnc).sCmn.indices.quantOffsetType = 1; + } + } + quant_offset = silk_Quantization_Offsets_Q10 + [((*psEnc).sCmn.indices.signalType as i32 >> 1) as usize] + [(*psEnc).sCmn.indices.quantOffsetType as usize] as i32 as f32 + / 1024.0f32; + (*psEncCtrl).Lambda = LAMBDA_OFFSET + + LAMBDA_DELAYED_DECISIONS * (*psEnc).sCmn.nStatesDelayedDecision as f32 + + LAMBDA_SPEECH_ACT * (*psEnc).sCmn.speech_activity_Q8 as f32 * (1.0f32 / 256.0f32) + + LAMBDA_INPUT_QUALITY * (*psEncCtrl).input_quality + + LAMBDA_CODING_QUALITY * (*psEncCtrl).coding_quality + + LAMBDA_QUANT_OFFSET * quant_offset; +} diff --git a/vendor/unsafe-libopus/src/silk/float/residual_energy_FLP.rs b/vendor/unsafe-libopus/src/silk/float/residual_energy_FLP.rs new file mode 100644 index 00000000..6e7b5fd8 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/residual_energy_FLP.rs @@ -0,0 +1,47 @@ +use crate::silk::define::MAX_NB_SUBFR; +use crate::silk::float::energy_FLP::silk_energy_FLP; +use crate::silk::float::LPC_analysis_filter_FLP::silk_LPC_analysis_filter_FLP; + +pub unsafe fn silk_residual_energy_FLP( + nrgs: *mut f32, + x: *const f32, + a: *mut [f32; 16], + gains: *const f32, + subfr_length: i32, + nb_subfr: i32, + LPC_order: i32, +) { + let mut shift: i32 = 0; + let mut LPC_res_ptr: *mut f32 = 0 as *mut f32; + let mut LPC_res: [f32; 192] = [0.; 192]; + LPC_res_ptr = LPC_res.as_mut_ptr().offset(LPC_order as isize); + shift = LPC_order + subfr_length; + silk_LPC_analysis_filter_FLP( + LPC_res.as_mut_ptr(), + (*a.offset(0 as isize)).as_mut_ptr() as *const f32, + x.offset((0 * shift) as isize), + 2 * shift, + LPC_order, + ); + *nrgs.offset(0 as isize) = ((*gains.offset(0 as isize) * *gains.offset(0 as isize)) as f64 + * silk_energy_FLP(LPC_res_ptr.offset((0 * shift) as isize), subfr_length)) + as f32; + *nrgs.offset(1 as isize) = ((*gains.offset(1 as isize) * *gains.offset(1 as isize)) as f64 + * silk_energy_FLP(LPC_res_ptr.offset((1 * shift) as isize), subfr_length)) + as f32; + if nb_subfr == MAX_NB_SUBFR { + silk_LPC_analysis_filter_FLP( + LPC_res.as_mut_ptr(), + (*a.offset(1 as isize)).as_mut_ptr() as *const f32, + x.offset((2 * shift) as isize), + 2 * shift, + LPC_order, + ); + *nrgs.offset(2 as isize) = ((*gains.offset(2 as isize) * *gains.offset(2 as isize)) as f64 + * silk_energy_FLP(LPC_res_ptr.offset((0 * shift) as isize), subfr_length)) + as f32; + *nrgs.offset(3 as isize) = ((*gains.offset(3 as isize) * *gains.offset(3 as isize)) as f64 + * silk_energy_FLP(LPC_res_ptr.offset((1 * shift) as isize), subfr_length)) + as f32; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/scale_copy_vector_FLP.rs b/vendor/unsafe-libopus/src/silk/float/scale_copy_vector_FLP.rs new file mode 100644 index 00000000..8e487281 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/scale_copy_vector_FLP.rs @@ -0,0 +1,22 @@ +pub unsafe fn silk_scale_copy_vector_FLP( + data_out: *mut f32, + data_in: *const f32, + gain: f32, + dataSize: i32, +) { + let mut i: i32 = 0; + let mut dataSize4: i32 = 0; + dataSize4 = dataSize & 0xfffc; + i = 0; + while i < dataSize4 { + *data_out.offset((i + 0) as isize) = gain * *data_in.offset((i + 0) as isize); + *data_out.offset((i + 1) as isize) = gain * *data_in.offset((i + 1) as isize); + *data_out.offset((i + 2) as isize) = gain * *data_in.offset((i + 2) as isize); + *data_out.offset((i + 3) as isize) = gain * *data_in.offset((i + 3) as isize); + i += 4; + } + while i < dataSize { + *data_out.offset(i as isize) = gain * *data_in.offset(i as isize); + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/scale_vector_FLP.rs b/vendor/unsafe-libopus/src/silk/float/scale_vector_FLP.rs new file mode 100644 index 00000000..f26c6b34 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/scale_vector_FLP.rs @@ -0,0 +1,17 @@ +pub unsafe fn silk_scale_vector_FLP(data1: *mut f32, gain: f32, dataSize: i32) { + let mut i: i32 = 0; + let mut dataSize4: i32 = 0; + dataSize4 = dataSize & 0xfffc; + i = 0; + while i < dataSize4 { + *data1.offset((i + 0) as isize) *= gain; + *data1.offset((i + 1) as isize) *= gain; + *data1.offset((i + 2) as isize) *= gain; + *data1.offset((i + 3) as isize) *= gain; + i += 4; + } + while i < dataSize { + *data1.offset(i as isize) *= gain; + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/schur_FLP.rs b/vendor/unsafe-libopus/src/silk/float/schur_FLP.rs new file mode 100644 index 00000000..7ef23844 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/schur_FLP.rs @@ -0,0 +1,38 @@ +pub unsafe fn silk_schur_FLP(refl_coef: *mut f32, auto_corr: *const f32, order: i32) -> f32 { + let mut k: i32 = 0; + let mut n: i32 = 0; + let mut C: [[f64; 2]; 25] = [[0.; 2]; 25]; + let mut Ctmp1: f64 = 0.; + let mut Ctmp2: f64 = 0.; + let mut rc_tmp: f64 = 0.; + assert!(order >= 0 && order <= 24); + k = 0; + loop { + C[k as usize][1 as usize] = *auto_corr.offset(k as isize) as f64; + C[k as usize][0 as usize] = C[k as usize][1 as usize]; + k += 1; + if !(k <= order) { + break; + } + } + k = 0; + while k < order { + rc_tmp = -C[(k + 1) as usize][0 as usize] + / (if C[0 as usize][1 as usize] > 1e-9f32 as f64 { + C[0 as usize][1 as usize] + } else { + 1e-9f32 as f64 + }); + *refl_coef.offset(k as isize) = rc_tmp as f32; + n = 0; + while n < order - k { + Ctmp1 = C[(n + k + 1) as usize][0 as usize]; + Ctmp2 = C[n as usize][1 as usize]; + C[(n + k + 1) as usize][0 as usize] = Ctmp1 + Ctmp2 * rc_tmp; + C[n as usize][1 as usize] = Ctmp2 + Ctmp1 * rc_tmp; + n += 1; + } + k += 1; + } + return C[0 as usize][1 as usize] as f32; +} diff --git a/vendor/unsafe-libopus/src/silk/float/sort_FLP.rs b/vendor/unsafe-libopus/src/silk/float/sort_FLP.rs new file mode 100644 index 00000000..1e09da86 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/sort_FLP.rs @@ -0,0 +1,41 @@ +pub unsafe fn silk_insertion_sort_decreasing_FLP(a: *mut f32, idx: *mut i32, L: i32, K: i32) { + let mut value: f32 = 0.; + let mut i: i32 = 0; + let mut j: i32 = 0; + assert!(K > 0); + assert!(L > 0); + assert!(L >= K); + i = 0; + while i < K { + *idx.offset(i as isize) = i; + i += 1; + } + i = 1; + while i < K { + value = *a.offset(i as isize); + j = i - 1; + while j >= 0 && value > *a.offset(j as isize) { + *a.offset((j + 1) as isize) = *a.offset(j as isize); + *idx.offset((j + 1) as isize) = *idx.offset(j as isize); + j -= 1; + } + *a.offset((j + 1) as isize) = value; + *idx.offset((j + 1) as isize) = i; + i += 1; + } + i = K; + while i < L { + value = *a.offset(i as isize); + if value > *a.offset((K - 1) as isize) { + j = K - 2; + while j >= 0 && value > *a.offset(j as isize) { + *a.offset((j + 1) as isize) = *a.offset(j as isize); + *idx.offset((j + 1) as isize) = *idx.offset(j as isize); + j -= 1; + } + *a.offset((j + 1) as isize) = value; + *idx.offset((j + 1) as isize) = i; + } + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/structs_FLP.rs b/vendor/unsafe-libopus/src/silk/float/structs_FLP.rs new file mode 100644 index 00000000..c317aa09 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/structs_FLP.rs @@ -0,0 +1,53 @@ +use crate::silk::structs::{silk_encoder_state, stereo_enc_state}; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_encoder { + pub state_Fxx: [silk_encoder_state_FLP; 2], + pub sStereo: stereo_enc_state, + pub nBitsUsedLBRR: i32, + pub nBitsExceeded: i32, + pub nChannelsAPI: i32, + pub nChannelsInternal: i32, + pub nPrevChannelsInternal: i32, + pub timeSinceSwitchAllowed_ms: i32, + pub allowBandwidthSwitch: i32, + pub prev_decode_only_middle: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_encoder_state_FLP { + pub sCmn: silk_encoder_state, + pub sShape: silk_shape_state_FLP, + pub x_buf: [f32; 720], + pub LTPCorr: f32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_shape_state_FLP { + pub LastGainIndex: i8, + pub HarmShapeGain_smth: f32, + pub Tilt_smth: f32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_encoder_control_FLP { + pub Gains: [f32; 4], + pub PredCoef: [[f32; 16]; 2], + pub LTPCoef: [f32; 20], + pub LTP_scale: f32, + pub pitchL: [i32; 4], + pub AR: [f32; 96], + pub LF_MA_shp: [f32; 4], + pub LF_AR_shp: [f32; 4], + pub Tilt: [f32; 4], + pub HarmShapeGain: [f32; 4], + pub Lambda: f32, + pub input_quality: f32, + pub coding_quality: f32, + pub predGain: f32, + pub LTPredCodGain: f32, + pub ResNrg: [f32; 4], + pub GainsUnq_Q16: [i32; 4], + pub lastGainIndexPrev: i8, +} diff --git a/vendor/unsafe-libopus/src/silk/float/warped_autocorrelation_FLP.rs b/vendor/unsafe-libopus/src/silk/float/warped_autocorrelation_FLP.rs new file mode 100644 index 00000000..bafaab38 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/warped_autocorrelation_FLP.rs @@ -0,0 +1,43 @@ +pub unsafe fn silk_warped_autocorrelation_FLP( + corr: *mut f32, + input: *const f32, + warping: f32, + length: i32, + order: i32, +) { + let mut n: i32 = 0; + let mut i: i32 = 0; + let mut tmp1: f64 = 0.; + let mut tmp2: f64 = 0.; + let mut state: [f64; 25] = [ + 0 as f64, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., + ]; + let mut C: [f64; 25] = [ + 0 as f64, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 0., 0., 0., 0., + ]; + assert!(order & 1 == 0); + n = 0; + while n < length { + tmp1 = *input.offset(n as isize) as f64; + i = 0; + while i < order { + tmp2 = state[i as usize] + warping as f64 * (state[(i + 1) as usize] - tmp1); + state[i as usize] = tmp1; + C[i as usize] += state[0 as usize] * tmp1; + tmp1 = state[(i + 1) as usize] + warping as f64 * (state[(i + 2) as usize] - tmp2); + state[(i + 1) as usize] = tmp2; + C[(i + 1) as usize] += state[0 as usize] * tmp2; + i += 2; + } + state[order as usize] = tmp1; + C[order as usize] += state[0 as usize] * tmp1; + n += 1; + } + i = 0; + while i < order + 1 { + *corr.offset(i as isize) = C[i as usize] as f32; + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/float/wrappers_FLP.rs b/vendor/unsafe-libopus/src/silk/float/wrappers_FLP.rs new file mode 100644 index 00000000..5dd46e53 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/float/wrappers_FLP.rs @@ -0,0 +1,225 @@ +use crate::silk::A2NLSF::silk_A2NLSF; +use crate::silk::NLSF2A::silk_NLSF2A; + +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub mod SigProc_FLP_h { + #[inline] + pub unsafe fn silk_float2int(x: f32) -> i32 { + return float2int(x); + } + use crate::celt::float_cast::float2int; +} + +pub use self::SigProc_FLP_h::silk_float2int; +use crate::silk::define::{LTP_ORDER, MAX_SHAPE_LPC_ORDER, TYPE_VOICED}; +use crate::silk::float::structs_FLP::{silk_encoder_control_FLP, silk_encoder_state_FLP}; +use crate::silk::process_NLSFs::silk_process_NLSFs; +use crate::silk::quant_LTP_gains::silk_quant_LTP_gains; +use crate::silk::structs::{silk_encoder_state, silk_nsq_state, SideInfoIndices}; +use crate::silk::tables_other::silk_LTPScales_table_Q14; +use crate::silk::NSQ_del_dec::silk_NSQ_del_dec_c; +use crate::silk::NSQ::silk_NSQ_c; + +pub unsafe fn silk_A2NLSF_FLP(NLSF_Q15: *mut i16, pAR: *const f32, LPC_order: i32) { + let mut i: i32 = 0; + let mut a_fix_Q16: [i32; 16] = [0; 16]; + i = 0; + while i < LPC_order { + a_fix_Q16[i as usize] = silk_float2int(*pAR.offset(i as isize) * 65536.0f32); + i += 1; + } + silk_A2NLSF(NLSF_Q15, a_fix_Q16.as_mut_ptr(), LPC_order); +} +pub unsafe fn silk_NLSF2A_FLP(pAR: *mut f32, NLSF_Q15: *const i16, LPC_order: i32, arch: i32) { + let mut i: i32 = 0; + let mut a_fix_Q12: [i16; 16] = [0; 16]; + silk_NLSF2A(a_fix_Q12.as_mut_ptr(), NLSF_Q15, LPC_order, arch); + i = 0; + while i < LPC_order { + *pAR.offset(i as isize) = a_fix_Q12[i as usize] as f32 * (1.0f32 / 4096.0f32); + i += 1; + } +} +pub unsafe fn silk_process_NLSFs_FLP( + psEncC: *mut silk_encoder_state, + PredCoef: *mut [f32; 16], + NLSF_Q15: *mut i16, + prev_NLSF_Q15: *const i16, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut PredCoef_Q12: [[i16; 16]; 2] = [[0; 16]; 2]; + silk_process_NLSFs(psEncC, PredCoef_Q12.as_mut_ptr(), NLSF_Q15, prev_NLSF_Q15); + j = 0; + while j < 2 { + i = 0; + while i < (*psEncC).predictLPCOrder { + (*PredCoef.offset(j as isize))[i as usize] = + PredCoef_Q12[j as usize][i as usize] as f32 * (1.0f32 / 4096.0f32); + i += 1; + } + j += 1; + } +} +pub unsafe fn silk_NSQ_wrapper_FLP( + psEnc: *mut silk_encoder_state_FLP, + psEncCtrl: *mut silk_encoder_control_FLP, + psIndices: *mut SideInfoIndices, + psNSQ: *mut silk_nsq_state, + pulses: *mut i8, + x: *const f32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut x16: [i16; 320] = [0; 320]; + let mut Gains_Q16: [i32; 4] = [0; 4]; + let mut PredCoef_Q12: [[i16; 16]; 2] = [[0; 16]; 2]; + let mut LTPCoef_Q14: [i16; 20] = [0; 20]; + let mut LTP_scale_Q14: i32 = 0; + let mut AR_Q13: [i16; 96] = [0; 96]; + let mut LF_shp_Q14: [i32; 4] = [0; 4]; + let mut Lambda_Q10: i32 = 0; + let mut Tilt_Q14: [i32; 4] = [0; 4]; + let mut HarmShapeGain_Q14: [i32; 4] = [0; 4]; + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + j = 0; + while j < (*psEnc).sCmn.shapingLPCOrder { + AR_Q13[(i * MAX_SHAPE_LPC_ORDER + j) as usize] = + silk_float2int((*psEncCtrl).AR[(i * MAX_SHAPE_LPC_ORDER + j) as usize] * 8192.0f32) + as i16; + j += 1; + } + i += 1; + } + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + LF_shp_Q14[i as usize] = + ((silk_float2int((*psEncCtrl).LF_AR_shp[i as usize] * 16384.0f32) as u32) << 16) as i32 + | silk_float2int((*psEncCtrl).LF_MA_shp[i as usize] * 16384.0f32) as u16 as i32; + Tilt_Q14[i as usize] = silk_float2int((*psEncCtrl).Tilt[i as usize] * 16384.0f32); + HarmShapeGain_Q14[i as usize] = + silk_float2int((*psEncCtrl).HarmShapeGain[i as usize] * 16384.0f32); + i += 1; + } + Lambda_Q10 = silk_float2int((*psEncCtrl).Lambda * 1024.0f32); + i = 0; + while i < (*psEnc).sCmn.nb_subfr * LTP_ORDER { + LTPCoef_Q14[i as usize] = + silk_float2int((*psEncCtrl).LTPCoef[i as usize] * 16384.0f32) as i16; + i += 1; + } + j = 0; + while j < 2 { + i = 0; + while i < (*psEnc).sCmn.predictLPCOrder { + PredCoef_Q12[j as usize][i as usize] = + silk_float2int((*psEncCtrl).PredCoef[j as usize][i as usize] * 4096.0f32) as i16; + i += 1; + } + j += 1; + } + i = 0; + while i < (*psEnc).sCmn.nb_subfr { + Gains_Q16[i as usize] = silk_float2int((*psEncCtrl).Gains[i as usize] * 65536.0f32); + i += 1; + } + if (*psIndices).signalType as i32 == TYPE_VOICED { + LTP_scale_Q14 = silk_LTPScales_table_Q14[(*psIndices).LTP_scaleIndex as usize] as i32; + } else { + LTP_scale_Q14 = 0; + } + i = 0; + while i < (*psEnc).sCmn.frame_length { + x16[i as usize] = silk_float2int(*x.offset(i as isize)) as i16; + i += 1; + } + if (*psEnc).sCmn.nStatesDelayedDecision > 1 || (*psEnc).sCmn.warping_Q16 > 0 { + silk_NSQ_del_dec_c( + &mut (*psEnc).sCmn, + psNSQ, + psIndices, + x16.as_mut_ptr() as *const i16, + pulses, + (PredCoef_Q12[0 as usize]).as_mut_ptr() as *const i16, + LTPCoef_Q14.as_mut_ptr() as *const i16, + AR_Q13.as_mut_ptr() as *const i16, + HarmShapeGain_Q14.as_mut_ptr() as *const i32, + Tilt_Q14.as_mut_ptr() as *const i32, + LF_shp_Q14.as_mut_ptr() as *const i32, + Gains_Q16.as_mut_ptr() as *const i32, + ((*psEncCtrl).pitchL).as_mut_ptr() as *const i32, + Lambda_Q10, + LTP_scale_Q14, + ); + } else { + silk_NSQ_c( + &mut (*psEnc).sCmn, + psNSQ, + psIndices, + x16.as_mut_ptr() as *const i16, + pulses, + (PredCoef_Q12[0 as usize]).as_mut_ptr() as *const i16, + LTPCoef_Q14.as_mut_ptr() as *const i16, + AR_Q13.as_mut_ptr() as *const i16, + HarmShapeGain_Q14.as_mut_ptr() as *const i32, + Tilt_Q14.as_mut_ptr() as *const i32, + LF_shp_Q14.as_mut_ptr() as *const i32, + Gains_Q16.as_mut_ptr() as *const i32, + ((*psEncCtrl).pitchL).as_mut_ptr() as *const i32, + Lambda_Q10, + LTP_scale_Q14, + ); + }; +} +pub unsafe fn silk_quant_LTP_gains_FLP( + B: *mut f32, + cbk_index: *mut i8, + periodicity_index: *mut i8, + sum_log_gain_Q7: *mut i32, + pred_gain_dB: *mut f32, + XX: *const f32, + xX: *const f32, + subfr_len: i32, + nb_subfr: i32, + arch: i32, +) { + let mut i: i32 = 0; + let mut pred_gain_dB_Q7: i32 = 0; + let mut B_Q14: [i16; 20] = [0; 20]; + let mut XX_Q17: [i32; 100] = [0; 100]; + let mut xX_Q17: [i32; 20] = [0; 20]; + i = 0; + while i < nb_subfr * LTP_ORDER * LTP_ORDER { + XX_Q17[i as usize] = silk_float2int(*XX.offset(i as isize) * 131072.0f32); + i += 1; + } + i = 0; + while i < nb_subfr * LTP_ORDER { + xX_Q17[i as usize] = silk_float2int(*xX.offset(i as isize) * 131072.0f32); + i += 1; + } + silk_quant_LTP_gains( + B_Q14.as_mut_ptr(), + cbk_index, + periodicity_index, + sum_log_gain_Q7, + &mut pred_gain_dB_Q7, + XX_Q17.as_mut_ptr() as *const i32, + xX_Q17.as_mut_ptr() as *const i32, + subfr_len, + nb_subfr, + arch, + ); + i = 0; + while i < nb_subfr * LTP_ORDER { + *B.offset(i as isize) = B_Q14[i as usize] as f32 * (1.0f32 / 16384.0f32); + i += 1; + } + *pred_gain_dB = pred_gain_dB_Q7 as f32 * (1.0f32 / 128.0f32); +} diff --git a/vendor/unsafe-libopus/src/silk/gain_quant.rs b/vendor/unsafe-libopus/src/silk/gain_quant.rs new file mode 100644 index 00000000..d3187d0d --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/gain_quant.rs @@ -0,0 +1,164 @@ +use crate::silk::lin2log::silk_lin2log; +use crate::silk::log2lin::silk_log2lin; +use crate::silk::SigProc_FIX::{silk_max_int, silk_min_32, silk_min_int}; + +use crate::silk::define::{ + MAX_DELTA_GAIN_QUANT, MIN_DELTA_GAIN_QUANT, MIN_QGAIN_DB, N_LEVELS_QGAIN, +}; + +pub const OFFSET: i32 = MIN_QGAIN_DB * 128 / 6 + 16 * 128; +pub unsafe fn silk_gains_quant( + ind: *mut i8, + gain_Q16: *mut i32, + prev_ind: *mut i8, + conditional: i32, + nb_subfr: i32, +) { + let mut k: i32 = 0; + let mut double_step_size_threshold: i32 = 0; + k = 0; + while k < nb_subfr { + *ind.offset(k as isize) = ((65536 * (64 - 1) / ((88 - 2) * 128 / 6)) as i64 + * (silk_lin2log(*gain_Q16.offset(k as isize)) - (2 * 128 / 6 + 16 * 128)) as i16 as i64 + >> 16) as i32 as i8; + if (*ind.offset(k as isize) as i32) < *prev_ind as i32 { + let ref mut fresh0 = *ind.offset(k as isize); + *fresh0 += 1; + } + *ind.offset(k as isize) = (if 0 > 64 - 1 { + if *ind.offset(k as isize) as i32 > 0 { + 0 + } else if (*ind.offset(k as isize) as i32) < 64 - 1 { + 64 - 1 + } else { + *ind.offset(k as isize) as i32 + } + } else if *ind.offset(k as isize) as i32 > 64 - 1 { + 64 - 1 + } else if (*ind.offset(k as isize) as i32) < 0 { + 0 + } else { + *ind.offset(k as isize) as i32 + }) as i8; + if k == 0 && conditional == 0 { + *ind.offset(k as isize) = (if *prev_ind as i32 + -(4) > 64 - 1 { + if *ind.offset(k as isize) as i32 > *prev_ind as i32 + -(4) { + *prev_ind as i32 + -(4) + } else if (*ind.offset(k as isize) as i32) < 64 - 1 { + 64 - 1 + } else { + *ind.offset(k as isize) as i32 + } + } else if *ind.offset(k as isize) as i32 > 64 - 1 { + 64 - 1 + } else if (*ind.offset(k as isize) as i32) < *prev_ind as i32 + -(4) { + *prev_ind as i32 + -(4) + } else { + *ind.offset(k as isize) as i32 + }) as i8; + *prev_ind = *ind.offset(k as isize); + } else { + *ind.offset(k as isize) = (*ind.offset(k as isize) as i32 - *prev_ind as i32) as i8; + double_step_size_threshold = + 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind as i32; + if *ind.offset(k as isize) as i32 > double_step_size_threshold { + *ind.offset(k as isize) = (double_step_size_threshold + + (*ind.offset(k as isize) as i32 - double_step_size_threshold + 1 >> 1)) + as i8; + } + *ind.offset(k as isize) = (if -(4) > 36 { + if *ind.offset(k as isize) as i32 > -(4) { + -(4) + } else if (*ind.offset(k as isize) as i32) < 36 { + 36 + } else { + *ind.offset(k as isize) as i32 + } + } else if *ind.offset(k as isize) as i32 > 36 { + 36 + } else if (*ind.offset(k as isize) as i32) < -(4) { + -(4) + } else { + *ind.offset(k as isize) as i32 + }) as i8; + if *ind.offset(k as isize) as i32 > double_step_size_threshold { + *prev_ind = (*prev_ind as i32 + + (((*ind.offset(k as isize) as u32) << 1) as i32 - double_step_size_threshold)) + as i8; + *prev_ind = silk_min_int(*prev_ind as i32, N_LEVELS_QGAIN - 1) as i8; + } else { + *prev_ind = (*prev_ind as i32 + *ind.offset(k as isize) as i32) as i8; + } + let ref mut fresh1 = *ind.offset(k as isize); + *fresh1 = (*fresh1 as i32 - MIN_DELTA_GAIN_QUANT) as i8; + } + *gain_Q16.offset(k as isize) = silk_log2lin(silk_min_32( + ((65536 * ((88 - 2) * 128 / 6) / (64 - 1)) as i64 * *prev_ind as i16 as i64 >> 16) + as i32 + + OFFSET, + 3967, + )); + k += 1; + } +} +pub unsafe fn silk_gains_dequant( + gain_Q16: *mut i32, + ind: *const i8, + prev_ind: *mut i8, + conditional: i32, + nb_subfr: i32, +) { + let mut k: i32 = 0; + let mut ind_tmp: i32 = 0; + let mut double_step_size_threshold: i32 = 0; + k = 0; + while k < nb_subfr { + if k == 0 && conditional == 0 { + *prev_ind = silk_max_int(*ind.offset(k as isize) as i32, *prev_ind as i32 - 16) as i8; + } else { + ind_tmp = *ind.offset(k as isize) as i32 + MIN_DELTA_GAIN_QUANT; + double_step_size_threshold = + 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind as i32; + if ind_tmp > double_step_size_threshold { + *prev_ind = (*prev_ind as i32 + + (((ind_tmp as u32) << 1) as i32 - double_step_size_threshold)) + as i8; + } else { + *prev_ind = (*prev_ind as i32 + ind_tmp) as i8; + } + } + *prev_ind = (if 0 > 64 - 1 { + if *prev_ind as i32 > 0 { + 0 + } else if (*prev_ind as i32) < 64 - 1 { + 64 - 1 + } else { + *prev_ind as i32 + } + } else if *prev_ind as i32 > 64 - 1 { + 64 - 1 + } else if (*prev_ind as i32) < 0 { + 0 + } else { + *prev_ind as i32 + }) as i8; + *gain_Q16.offset(k as isize) = silk_log2lin(silk_min_32( + ((65536 * ((88 - 2) * 128 / 6) / (64 - 1)) as i64 * *prev_ind as i16 as i64 >> 16) + as i32 + + OFFSET, + 3967, + )); + k += 1; + } +} +pub unsafe fn silk_gains_ID(ind: *const i8, nb_subfr: i32) -> i32 { + let mut k: i32 = 0; + let mut gainsID: i32 = 0; + gainsID = 0; + k = 0; + while k < nb_subfr { + gainsID = *ind.offset(k as isize) as i32 + ((gainsID as u32) << 8) as i32; + k += 1; + } + return gainsID; +} diff --git a/vendor/unsafe-libopus/src/silk/init_decoder.rs b/vendor/unsafe-libopus/src/silk/init_decoder.rs new file mode 100644 index 00000000..cd0e3a58 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/init_decoder.rs @@ -0,0 +1,26 @@ +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} + +use self::cpu_support_h::opus_select_arch; +use crate::externs::memset; +use crate::silk::structs::silk_decoder_state; +use crate::silk::CNG::silk_CNG_Reset; +use crate::silk::PLC::silk_PLC_Reset; + +pub unsafe fn silk_init_decoder(psDec: *mut silk_decoder_state) -> i32 { + memset( + psDec as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + (*psDec).first_frame_after_reset = 1; + (*psDec).prev_gain_Q16 = 65536; + (*psDec).arch = opus_select_arch(); + silk_CNG_Reset(psDec); + silk_PLC_Reset(psDec); + return 0; +} diff --git a/vendor/unsafe-libopus/src/silk/init_encoder.rs b/vendor/unsafe-libopus/src/silk/init_encoder.rs new file mode 100644 index 00000000..2460c665 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/init_encoder.rs @@ -0,0 +1,21 @@ +use crate::externs::memset; +use crate::silk::float::structs_FLP::silk_encoder_state_FLP; +use crate::silk::lin2log::silk_lin2log; +use crate::silk::VAD::silk_VAD_Init; + +pub unsafe fn silk_init_encoder(psEnc: *mut silk_encoder_state_FLP, arch: i32) -> i32 { + let mut ret: i32 = 0; + memset( + psEnc as *mut core::ffi::c_void, + 0, + ::core::mem::size_of::() as u64, + ); + (*psEnc).sCmn.arch = arch; + (*psEnc).sCmn.variable_HP_smth1_Q15 = + (((silk_lin2log(((60 * ((1) << 16)) as f64 + 0.5f64) as i32) - ((16) << 7)) as u32) << 8) + as i32; + (*psEnc).sCmn.variable_HP_smth2_Q15 = (*psEnc).sCmn.variable_HP_smth1_Q15; + (*psEnc).sCmn.first_frame_after_reset = 1; + ret += silk_VAD_Init(&mut (*psEnc).sCmn.sVAD); + return ret; +} diff --git a/vendor/unsafe-libopus/src/silk/inner_prod_aligned.rs b/vendor/unsafe-libopus/src/silk/inner_prod_aligned.rs new file mode 100644 index 00000000..8479631a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/inner_prod_aligned.rs @@ -0,0 +1,16 @@ +pub unsafe fn silk_inner_prod_aligned_scale( + inVec1: *const i16, + inVec2: *const i16, + scale: i32, + len: i32, +) -> i32 { + let mut i: i32 = 0; + let mut sum: i32 = 0; + i = 0; + while i < len { + sum = + sum + (*inVec1.offset(i as isize) as i32 * *inVec2.offset(i as isize) as i32 >> scale); + i += 1; + } + return sum; +} diff --git a/vendor/unsafe-libopus/src/silk/interpolate.rs b/vendor/unsafe-libopus/src/silk/interpolate.rs new file mode 100644 index 00000000..83bedfd3 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/interpolate.rs @@ -0,0 +1,20 @@ +// Interpolate two vectors +pub fn silk_interpolate( + xi: &mut [i16], + x0: &[i16], + x1: &[i16], + // interp. factor, weight on 2nd vector + ifact_Q2: i32, +) { + assert_eq!(xi.len(), x0.len()); + assert_eq!(xi.len(), x1.len()); + + assert!(ifact_Q2 >= 0); + assert!(ifact_Q2 <= 4); + + for (xi, (x0, x1)) in xi.iter_mut().zip(x0.iter().zip(x1)) { + *xi = (*x0 as i32 + + (((*x1 as i32 - *x0 as i32) as i16 as i32 * ifact_Q2 as i16 as i32) >> 2)) + as i16 + } +} diff --git a/vendor/unsafe-libopus/src/silk/lin2log.rs b/vendor/unsafe-libopus/src/silk/lin2log.rs new file mode 100644 index 00000000..705f3c42 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/lin2log.rs @@ -0,0 +1,9 @@ +use crate::silk::Inlines::silk_CLZ_FRAC; + +pub unsafe fn silk_lin2log(inLin: i32) -> i32 { + let mut lz: i32 = 0; + let mut frac_Q7: i32 = 0; + silk_CLZ_FRAC(inLin, &mut lz, &mut frac_Q7); + return (frac_Q7 as i64 + ((frac_Q7 * (128 - frac_Q7)) as i64 * 179 as i64 >> 16)) as i32 + + (((31 - lz) as u32) << 7) as i32; +} diff --git a/vendor/unsafe-libopus/src/silk/log2lin.rs b/vendor/unsafe-libopus/src/silk/log2lin.rs new file mode 100644 index 00000000..b297aa9c --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/log2lin.rs @@ -0,0 +1,36 @@ +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; +} + +pub use self::typedef_h::silk_int32_MAX; + +pub unsafe fn silk_log2lin(inLog_Q7: i32) -> i32 { + let mut out: i32 = 0; + let mut frac_Q7: i32 = 0; + if inLog_Q7 < 0 { + return 0; + } else { + if inLog_Q7 >= 3967 { + return silk_int32_MAX; + } + } + out = ((1) << (inLog_Q7 >> 7)) as i32; + frac_Q7 = inLog_Q7 & 0x7f; + if inLog_Q7 < 2048 { + out = out + + (out + * (frac_Q7 as i64 + + ((frac_Q7 as i16 as i32 * (128 - frac_Q7) as i16 as i32) as i64 + * -(174) as i16 as i64 + >> 16)) as i32 + >> 7); + } else { + out = out + + (out >> 7) + * (frac_Q7 as i64 + + ((frac_Q7 as i16 as i32 * (128 - frac_Q7) as i16 as i32) as i64 + * -(174) as i16 as i64 + >> 16)) as i32; + } + return out; +} diff --git a/vendor/unsafe-libopus/src/silk/macros.rs b/vendor/unsafe-libopus/src/silk/macros.rs new file mode 100644 index 00000000..5a2343f8 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/macros.rs @@ -0,0 +1,10 @@ +pub const EC_CLZ0: i32 = 32; + +#[inline] +pub fn silk_CLZ32(in32: i32) -> i32 { + return if in32 != 0 { + 32 - (EC_CLZ0 - (in32.leading_zeros() as i32)) + } else { + 32 + }; +} diff --git a/vendor/unsafe-libopus/src/silk/mathops.rs b/vendor/unsafe-libopus/src/silk/mathops.rs new file mode 100644 index 00000000..68da1c55 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/mathops.rs @@ -0,0 +1,3 @@ +pub fn silk_exp2(x: f32) -> f32 { + 2f64.powf(x as f64) as f32 +} diff --git a/vendor/unsafe-libopus/src/silk/pitch_est_tables.rs b/vendor/unsafe-libopus/src/silk/pitch_est_tables.rs new file mode 100644 index 00000000..86220d3a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/pitch_est_tables.rs @@ -0,0 +1,62 @@ +pub const PE_NB_CBKS_STAGE3_MIN: i32 = 16; +pub const PE_NB_CBKS_STAGE3_MID: i32 = 24; +pub const PE_NB_CBKS_STAGE3_MAX: i32 = 34; +pub const PE_NB_CBKS_STAGE3_10MS: i32 = 12; +pub const PE_NB_STAGE3_LAGS: i32 = 5; +pub const PE_NB_CBKS_STAGE2_EXT: i32 = 11; +pub const PE_NB_CBKS_STAGE2_10MS: i32 = 3; +pub const PE_MAX_NB_SUBFR: i32 = 4; +pub const PE_SUBFR_LENGTH_MS: i32 = 5; +pub const PE_LTP_MEM_LENGTH_MS: i32 = 4 * PE_SUBFR_LENGTH_MS; +pub const PE_MAX_LAG_MS: i32 = 18; +pub const PE_MIN_LAG_MS: i32 = 2; +pub const PE_NB_CBKS_STAGE2: i32 = 3; + +pub const SILK_PE_MIN_COMPLEX: i32 = 0; +pub const SILK_PE_MID_COMPLEX: i32 = 1; +pub const SILK_PE_MAX_COMPLEX: i32 = 2; + +pub const PE_SHORTLAG_BIAS: f32 = 0.2f32; +pub const PE_PREVLAG_BIAS: f32 = 0.2f32; +pub const PE_FLATCONTOUR_BIAS: f32 = 0.05f32; + +pub static silk_CB_lags_stage2_10_ms: [[i8; 3]; 2] = [[0, 1, 0], [0, 0, 1]]; +pub static silk_CB_lags_stage3_10_ms: [[i8; 12]; 2] = [ + [0, 0, 1, -1, 1, -1, 2, -2, 2, -2, 3, -3], + [0, 1, 0, 1, -1, 2, -1, 2, -2, 3, -2, 3], +]; +pub static silk_Lag_range_stage3_10_ms: [[i8; 2]; 2] = [[-3, 7], [-2, 7]]; +pub static silk_CB_lags_stage2: [[i8; 11]; 4] = [ + [0, 2, -1, -1, -1, 0, 0, 1, 1, 0, 1], + [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], + [0, -1, 2, 1, 0, 1, 1, 0, 0, -1, -1], +]; +pub static silk_CB_lags_stage3: [[i8; 34]; 4] = [ + [ + 0, 0, 1, -1, 0, 1, -1, 0, -1, 1, -2, 2, -2, -2, 2, -3, 2, 3, -3, -4, 3, -4, 4, 4, -5, 5, + -6, -5, 6, -7, 6, 5, 8, -9, + ], + [ + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 1, -1, 0, 1, -1, -1, 1, -1, 2, 1, -1, 2, -2, -2, + 2, -2, 2, 2, 3, -3, + ], + [ + 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, -1, 1, 0, 0, 2, 1, -1, 2, -1, -1, 2, -1, 2, 2, + -1, 3, -2, -2, -2, 3, + ], + [ + 0, 1, 0, 0, 1, 0, 1, -1, 2, -1, 2, -1, 2, 3, -2, 3, -2, -2, 4, 4, -3, 5, -3, -4, 6, -4, 6, + 5, -5, 8, -6, -5, -7, 9, + ], +]; +pub static silk_Lag_range_stage3: [[[i8; 2]; 4]; 3] = [ + [[-5, 8], [-1, 6], [-1, 6], [-4, 10]], + [[-6, 10], [-2, 6], [-1, 6], [-5, 10]], + [[-9, 12], [-3, 7], [-2, 7], [-7, 13]], +]; +pub static silk_nb_cbk_searchs_stage3: [i8; 3] = [ + PE_NB_CBKS_STAGE3_MIN as i8, + PE_NB_CBKS_STAGE3_MID as i8, + PE_NB_CBKS_STAGE3_MAX as i8, +]; diff --git a/vendor/unsafe-libopus/src/silk/process_NLSFs.rs b/vendor/unsafe-libopus/src/silk/process_NLSFs.rs new file mode 100644 index 00000000..e65b7545 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/process_NLSFs.rs @@ -0,0 +1,97 @@ +use crate::externs::memcpy; +use crate::silk::interpolate::silk_interpolate; +use crate::silk::structs::silk_encoder_state; +use crate::silk::NLSF_VQ_weights_laroia::silk_NLSF_VQ_weights_laroia; +use crate::silk::NLSF_encode::silk_NLSF_encode; +use crate::silk::NLSF2A::silk_NLSF2A; + +pub unsafe fn silk_process_NLSFs( + psEncC: *mut silk_encoder_state, + PredCoef_Q12: *mut [i16; 16], + pNLSF_Q15: *mut i16, + prev_NLSFq_Q15: *const i16, +) { + let mut i: i32 = 0; + let mut doInterpolate: i32 = 0; + let mut NLSF_mu_Q20: i32 = 0; + let mut i_sqr_Q15: i16 = 0; + let mut pNLSF0_temp_Q15: [i16; 16] = [0; 16]; + let mut pNLSFW_QW: [i16; 16] = [0; 16]; + let mut pNLSFW0_temp_QW: [i16; 16] = [0; 16]; + assert!( + (*psEncC).useInterpolatedNLSFs == 1 + || (*psEncC).indices.NLSFInterpCoef_Q2 as i32 == (1) << 2 + ); + NLSF_mu_Q20 = ((0.003f64 * ((1) << 20) as f64 + 0.5f64) as i32 as i64 + + ((-0.001f64 * ((1) << 28) as f64 + 0.5f64) as i32 as i64 + * (*psEncC).speech_activity_Q8 as i16 as i64 + >> 16)) as i32; + if (*psEncC).nb_subfr == 2 { + NLSF_mu_Q20 = NLSF_mu_Q20 + (NLSF_mu_Q20 >> 1); + } + assert!(NLSF_mu_Q20 > 0); + silk_NLSF_VQ_weights_laroia( + &mut pNLSFW_QW[..(*psEncC).predictLPCOrder as usize], + std::slice::from_raw_parts(pNLSF_Q15, (*psEncC).predictLPCOrder as usize), + ); + doInterpolate = ((*psEncC).useInterpolatedNLSFs == 1 + && ((*psEncC).indices.NLSFInterpCoef_Q2 as i32) < 4) as i32; + if doInterpolate != 0 { + silk_interpolate( + &mut pNLSF0_temp_Q15[..(*psEncC).predictLPCOrder as usize], + std::slice::from_raw_parts(prev_NLSFq_Q15, (*psEncC).predictLPCOrder as usize), + std::slice::from_raw_parts(pNLSF_Q15, (*psEncC).predictLPCOrder as usize), + (*psEncC).indices.NLSFInterpCoef_Q2 as i32, + ); + silk_NLSF_VQ_weights_laroia( + &mut pNLSFW0_temp_QW[..(*psEncC).predictLPCOrder as usize], + &pNLSF0_temp_Q15[..(*psEncC).predictLPCOrder as usize], + ); + i_sqr_Q15 = ((((*psEncC).indices.NLSFInterpCoef_Q2 as i16 as i32 + * (*psEncC).indices.NLSFInterpCoef_Q2 as i16 as i32) as u32) + << 11) as i32 as i16; + i = 0; + while i < (*psEncC).predictLPCOrder { + pNLSFW_QW[i as usize] = ((pNLSFW_QW[i as usize] as i32 >> 1) + + (pNLSFW0_temp_QW[i as usize] as i32 * i_sqr_Q15 as i32 >> 16)) + as i16; + i += 1; + } + } + silk_NLSF_encode( + ((*psEncC).indices.NLSFIndices).as_mut_ptr(), + pNLSF_Q15, + (*psEncC).psNLSF_CB, + pNLSFW_QW.as_mut_ptr(), + NLSF_mu_Q20, + (*psEncC).NLSF_MSVQ_Survivors, + (*psEncC).indices.signalType as i32, + ); + silk_NLSF2A( + (*PredCoef_Q12.offset(1 as isize)).as_mut_ptr(), + pNLSF_Q15 as *const i16, + (*psEncC).predictLPCOrder, + (*psEncC).arch, + ); + if doInterpolate != 0 { + silk_interpolate( + &mut pNLSF0_temp_Q15[..(*psEncC).predictLPCOrder as usize], + std::slice::from_raw_parts(prev_NLSFq_Q15, (*psEncC).predictLPCOrder as usize), + std::slice::from_raw_parts(pNLSF_Q15 as *const i16, (*psEncC).predictLPCOrder as usize), + (*psEncC).indices.NLSFInterpCoef_Q2 as i32, + ); + silk_NLSF2A( + (*PredCoef_Q12.offset(0 as isize)).as_mut_ptr(), + pNLSF0_temp_Q15.as_mut_ptr(), + (*psEncC).predictLPCOrder, + (*psEncC).arch, + ); + } else { + assert!((*psEncC).predictLPCOrder <= 16); + memcpy( + (*PredCoef_Q12.offset(0 as isize)).as_mut_ptr() as *mut core::ffi::c_void, + (*PredCoef_Q12.offset(1 as isize)).as_mut_ptr() as *const core::ffi::c_void, + ((*psEncC).predictLPCOrder as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + }; +} diff --git a/vendor/unsafe-libopus/src/silk/quant_LTP_gains.rs b/vendor/unsafe-libopus/src/silk/quant_LTP_gains.rs new file mode 100644 index 00000000..94b00c73 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/quant_LTP_gains.rs @@ -0,0 +1,139 @@ +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; +} +pub use self::typedef_h::silk_int32_MAX; +use crate::externs::memcpy; +use crate::silk::define::LTP_ORDER; +use crate::silk::lin2log::silk_lin2log; +use crate::silk::log2lin::silk_log2lin; +use crate::silk::tables_LTP::{ + silk_LTP_gain_BITS_Q5_ptrs, silk_LTP_vq_gain_ptrs_Q7, silk_LTP_vq_ptrs_Q7, silk_LTP_vq_sizes, +}; +use crate::silk::VQ_WMat_EC::silk_VQ_WMat_EC_c; + +pub unsafe fn silk_quant_LTP_gains( + B_Q14: *mut i16, + cbk_index: *mut i8, + periodicity_index: *mut i8, + sum_log_gain_Q7: *mut i32, + pred_gain_dB_Q7: *mut i32, + XX_Q17: *const i32, + xX_Q17: *const i32, + subfr_len: i32, + nb_subfr: i32, + _arch: i32, +) { + let mut j: i32 = 0; + let mut k: i32 = 0; + let mut cbk_size: i32 = 0; + let mut temp_idx: [i8; 4] = [0; 4]; + let mut cl_ptr_Q5: *const u8 = 0 as *const u8; + let mut cbk_ptr_Q7: *const i8 = 0 as *const i8; + let mut cbk_gain_ptr_Q7: *const u8 = 0 as *const u8; + let mut XX_Q17_ptr: *const i32 = 0 as *const i32; + let mut xX_Q17_ptr: *const i32 = 0 as *const i32; + let mut res_nrg_Q15_subfr: i32 = 0; + let mut res_nrg_Q15: i32 = 0; + let mut rate_dist_Q7_subfr: i32 = 0; + let mut rate_dist_Q7: i32 = 0; + let mut min_rate_dist_Q7: i32 = 0; + let mut sum_log_gain_tmp_Q7: i32 = 0; + let mut best_sum_log_gain_Q7: i32 = 0; + let mut max_gain_Q7: i32 = 0; + let mut gain_Q7: i32 = 0; + min_rate_dist_Q7 = silk_int32_MAX; + best_sum_log_gain_Q7 = 0; + k = 0; + while k < 3 { + let gain_safety: i32 = (0.4f64 * ((1) << 7) as f64 + 0.5f64) as i32; + cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[k as usize].as_ptr(); + cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[k as usize]; + cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[k as usize]; + cbk_size = silk_LTP_vq_sizes[k as usize] as i32; + XX_Q17_ptr = XX_Q17; + xX_Q17_ptr = xX_Q17; + res_nrg_Q15 = 0; + rate_dist_Q7 = 0; + sum_log_gain_tmp_Q7 = *sum_log_gain_Q7; + j = 0; + while j < nb_subfr { + max_gain_Q7 = silk_log2lin( + (250.0f32 as f64 / 6.0f64 * ((1) << 7) as f64 + 0.5f64) as i32 + - sum_log_gain_tmp_Q7 + + ((7 * ((1) << 7)) as f64 + 0.5f64) as i32, + ) - gain_safety; + silk_VQ_WMat_EC_c( + &mut *temp_idx.as_mut_ptr().offset(j as isize), + &mut res_nrg_Q15_subfr, + &mut rate_dist_Q7_subfr, + &mut gain_Q7, + XX_Q17_ptr, + xX_Q17_ptr, + cbk_ptr_Q7, + cbk_gain_ptr_Q7, + cl_ptr_Q5, + subfr_len, + max_gain_Q7, + cbk_size, + ); + res_nrg_Q15 = if (res_nrg_Q15 as u32).wrapping_add(res_nrg_Q15_subfr as u32) + & 0x80000000 as u32 + != 0 + { + silk_int32_MAX + } else { + res_nrg_Q15 + res_nrg_Q15_subfr + }; + rate_dist_Q7 = if (rate_dist_Q7 as u32).wrapping_add(rate_dist_Q7_subfr as u32) + & 0x80000000 as u32 + != 0 + { + silk_int32_MAX + } else { + rate_dist_Q7 + rate_dist_Q7_subfr + }; + sum_log_gain_tmp_Q7 = if 0 > sum_log_gain_tmp_Q7 + silk_lin2log(gain_safety + gain_Q7) + - ((7 * ((1) << 7)) as f64 + 0.5f64) as i32 + { + 0 + } else { + sum_log_gain_tmp_Q7 + silk_lin2log(gain_safety + gain_Q7) + - ((7 * ((1) << 7)) as f64 + 0.5f64) as i32 + }; + XX_Q17_ptr = XX_Q17_ptr.offset((LTP_ORDER * LTP_ORDER) as isize); + xX_Q17_ptr = xX_Q17_ptr.offset(LTP_ORDER as isize); + j += 1; + } + if rate_dist_Q7 <= min_rate_dist_Q7 { + min_rate_dist_Q7 = rate_dist_Q7; + *periodicity_index = k as i8; + memcpy( + cbk_index as *mut core::ffi::c_void, + temp_idx.as_mut_ptr() as *const core::ffi::c_void, + (nb_subfr as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7; + } + k += 1; + } + cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[*periodicity_index as usize]; + j = 0; + while j < nb_subfr { + k = 0; + while k < LTP_ORDER { + *B_Q14.offset((j * LTP_ORDER + k) as isize) = ((*cbk_ptr_Q7 + .offset((*cbk_index.offset(j as isize) as i32 * 5 + k) as isize) + as u32) + << 7) as i32 as i16; + k += 1; + } + j += 1; + } + if nb_subfr == 2 { + res_nrg_Q15 = res_nrg_Q15 >> 1; + } else { + res_nrg_Q15 = res_nrg_Q15 >> 2; + } + *sum_log_gain_Q7 = best_sum_log_gain_Q7; + *pred_gain_dB_Q7 = -(3) as i16 as i32 * (silk_lin2log(res_nrg_Q15) - ((15) << 7)) as i16 as i32; +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/ar2.rs b/vendor/unsafe-libopus/src/silk/resampler/ar2.rs new file mode 100644 index 00000000..5de039d9 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/ar2.rs @@ -0,0 +1,18 @@ +/* Second order AR filter with single delay elements */ +pub fn silk_resampler_private_AR2( + state: &mut [i32; 2], + out_Q8: &mut [i32], + in_0: &[i16], + A_Q14: &[i16], +) { + assert_eq!(out_Q8.len(), in_0.len()); + + for k in 0..in_0.len() { + let out32 = state[0] + ((in_0[k] as i32 as u32) << 8) as i32; + out_Q8[k] = out32; + + let out32 = ((out32 as u32) << 2) as i32; + state[0] = (state[1] as i64 + ((out32 as i64 * A_Q14[0] as i64) >> 16)) as i32; + state[1] = ((out32 as i64 * A_Q14[1] as i64) >> 16) as i32; + } +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/down2.rs b/vendor/unsafe-libopus/src/silk/resampler/down2.rs new file mode 100644 index 00000000..a7a638a4 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/down2.rs @@ -0,0 +1,47 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +use super::rom::{silk_resampler_down2_0, silk_resampler_down2_1}; + +pub fn silk_resampler_down2(S: &mut [i32; 2], out: &mut [i16], in_0: &[i16]) { + assert_eq!(out.len() * 2, in_0.len()); + + assert!(silk_resampler_down2_0 as i32 > 0); + assert!((silk_resampler_down2_1 as i32) < 0); + for k in 0..out.len() { + let in32 = ((in_0[2 * k] as i32 as u32) << 10) as i32; + let Y = in32 - S[0]; + let X = (Y as i64 + ((Y as i64 * silk_resampler_down2_1 as i64) >> 16)) as i32; + let mut out32 = S[0] + X; + S[0] = in32 + X; + + let in32 = ((in_0[2 * k + 1] as i32 as u32) << 10) as i32; + let Y = in32 - S[1]; + let X = (Y as i64 * silk_resampler_down2_0 as i64 >> 16) as i32; + out32 += S[1]; + out32 += X; + S[1] = in32 + X; + + out[k] = (if (if 11 == 1 { + (out32 >> 1) + (out32 & 1) + } else { + (out32 >> 11 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 11 == 1 { + (out32 >> 1) + (out32 & 1) + } else { + (out32 >> 11 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 11 == 1 { + (out32 >> 1) + (out32 & 1) + } else { + (out32 >> 11 - 1) + 1 >> 1 + }) as i16; + } +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/down2_3.rs b/vendor/unsafe-libopus/src/silk/resampler/down2_3.rs new file mode 100644 index 00000000..bafa4ce2 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/down2_3.rs @@ -0,0 +1,114 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +use arrayref::array_mut_ref; + +use super::ar2::silk_resampler_private_AR2; +use super::rom::silk_Resampler_2_3_COEFS_LQ; +use crate::silk::resampler::RESAMPLER_MAX_BATCH_SIZE_IN; + +const ORDER_FIR: usize = 4; + +/// Downsample by a factor 2/3, low quality +pub fn silk_resampler_down2_3(state: &mut [i32; 6], mut out: &mut [i16], mut in_0: &[i16]) { + let mut nSamplesIn: usize = 0; + let mut res_Q6: i32 = 0; + let mut buf: [i32; RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR] = + [0; RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR]; + + let s = state; + + buf[..ORDER_FIR].copy_from_slice(&s[..ORDER_FIR]); + + loop { + nSamplesIn = in_0.len().min(RESAMPLER_MAX_BATCH_SIZE_IN); + silk_resampler_private_AR2( + array_mut_ref![s, ORDER_FIR, 2], + &mut buf[ORDER_FIR..][..nSamplesIn], + &in_0[..nSamplesIn], + &silk_Resampler_2_3_COEFS_LQ, + ); + let mut buf_ptr = buf.as_mut_slice(); + let mut counter = nSamplesIn; + while counter > 2 { + res_Q6 = (buf_ptr[0] as i64 * silk_Resampler_2_3_COEFS_LQ[2] as i64 >> 16) as i32; + res_Q6 = (res_Q6 as i64 + + (buf_ptr[1] as i64 * silk_Resampler_2_3_COEFS_LQ[3] as i64 >> 16)) + as i32; + res_Q6 = (res_Q6 as i64 + + (buf_ptr[2] as i64 * silk_Resampler_2_3_COEFS_LQ[5] as i64 >> 16)) + as i32; + res_Q6 = (res_Q6 as i64 + + (buf_ptr[3] as i64 * silk_Resampler_2_3_COEFS_LQ[4] as i64 >> 16)) + as i32; + + out[0] = (if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) as i16; + out = &mut out[1..]; + + res_Q6 = (buf_ptr[1] as i64 * silk_Resampler_2_3_COEFS_LQ[4] as i64 >> 16) as i32; + res_Q6 = (res_Q6 as i64 + + (buf_ptr[2] as i64 * silk_Resampler_2_3_COEFS_LQ[5] as i64 >> 16)) + as i32; + res_Q6 = (res_Q6 as i64 + + (buf_ptr[3] as i64 * silk_Resampler_2_3_COEFS_LQ[3] as i64 >> 16)) + as i32; + res_Q6 = (res_Q6 as i64 + + (buf_ptr[4] as i64 * silk_Resampler_2_3_COEFS_LQ[2] as i64 >> 16)) + as i32; + + out[0] = (if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) as i16; + out = &mut out[1..]; + + buf_ptr = &mut buf_ptr[3..]; + counter -= 3; + } + + in_0 = &in_0[nSamplesIn..]; + if in_0.is_empty() { + break; + } + + buf.copy_within(nSamplesIn..nSamplesIn + ORDER_FIR, 0); + } + + s[..ORDER_FIR].copy_from_slice(&buf[nSamplesIn..][..ORDER_FIR]); +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/down_fir.rs b/vendor/unsafe-libopus/src/silk/resampler/down_fir.rs new file mode 100644 index 00000000..20bd058b --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/down_fir.rs @@ -0,0 +1,255 @@ +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int16_MIN: i32 = i16::MIN as i32; +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +use super::ar2::silk_resampler_private_AR2; +use super::rom::{RESAMPLER_DOWN_ORDER_FIR0, RESAMPLER_DOWN_ORDER_FIR1, RESAMPLER_DOWN_ORDER_FIR2}; +use crate::silk::resampler::{ResamplerParams, SILK_RESAMPLER_MAX_FIR_ORDER}; + +#[derive(Copy, Clone)] +pub struct ResamplerDownFirParams { + pub fir_order: usize, + pub fir_fracs: i32, + pub coefs: &'static [i16], +} + +#[derive(Copy, Clone)] +pub struct ResamplerDownFirState { + ar2_state: [i32; 2], + fir_state: [i32; SILK_RESAMPLER_MAX_FIR_ORDER], +} + +// can't derive Default because of the array size +impl Default for ResamplerDownFirState { + fn default() -> Self { + ResamplerDownFirState { + ar2_state: [0; 2], + fir_state: [0; SILK_RESAMPLER_MAX_FIR_ORDER], + } + } +} + +#[inline] +fn silk_resampler_private_down_FIR_INTERPOL<'a>( + mut out: &'a mut [i16], + buf: &[i32], + FIR_Coefs: &[i16], + FIR_Order: usize, + FIR_Fracs: i32, + max_index_Q16: i32, + index_increment_Q16: i32, +) -> &'a mut [i16] { + match FIR_Order { + RESAMPLER_DOWN_ORDER_FIR0 => { + let mut index_Q16 = 0; + while index_Q16 < max_index_Q16 { + /* Integer part gives pointer to buffered input */ + let buf_ptr = &buf[(index_Q16 >> 16) as usize..]; + + /* Fractional part gives interpolation coefficients */ + let interpol_ind = + (((index_Q16 & 0xffff) as i64 * FIR_Fracs as i16 as i64) >> 16) as usize; + + /* Inner product */ + let interpol_ptr = &FIR_Coefs[(RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind)..]; + let mut res_Q6 = ((buf_ptr[0] as i64 * interpol_ptr[0] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[1] as i64 * interpol_ptr[1] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[2] as i64 * interpol_ptr[2] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[3] as i64 * interpol_ptr[3] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[4] as i64 * interpol_ptr[4] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[5] as i64 * interpol_ptr[5] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[6] as i64 * interpol_ptr[6] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[7] as i64 * interpol_ptr[7] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[8] as i64 * interpol_ptr[8] as i64) >> 16) as i32; + + let interpol_ptr = &FIR_Coefs + [(RESAMPLER_DOWN_ORDER_FIR0 / 2 * (FIR_Fracs as usize - 1 - interpol_ind))..]; + res_Q6 += ((buf_ptr[17] as i64 * interpol_ptr[0] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[16] as i64 * interpol_ptr[1] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[15] as i64 * interpol_ptr[2] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[14] as i64 * interpol_ptr[3] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[13] as i64 * interpol_ptr[4] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[12] as i64 * interpol_ptr[5] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[11] as i64 * interpol_ptr[6] as i64) >> 16) as i32; + res_Q6 += ((buf_ptr[10] as i64 * interpol_ptr[7] as i64) >> 16) as i32; + res_Q6 += (buf_ptr[9] as i64 * interpol_ptr[8] as i64 >> 16) as i32; + + /* Scale down, saturate and store in output array */ + out[0] = (if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) as i16; + out = &mut out[1..]; + + index_Q16 += index_increment_Q16; + } + } + RESAMPLER_DOWN_ORDER_FIR1 => { + let mut index_Q16 = 0; + while index_Q16 < max_index_Q16 { + /* Integer part gives pointer to buffered input */ + let buf_ptr = &buf[(index_Q16 >> 16) as usize..]; + + let mut res_Q6 = + (((buf_ptr[0] + buf_ptr[23]) as i64 * FIR_Coefs[0] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[1] + buf_ptr[22]) as i64 * FIR_Coefs[1] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[2] + buf_ptr[21]) as i64 * FIR_Coefs[2] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[3] + buf_ptr[20]) as i64 * FIR_Coefs[3] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[4] + buf_ptr[19]) as i64 * FIR_Coefs[4] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[5] + buf_ptr[18]) as i64 * FIR_Coefs[5] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[6] + buf_ptr[17]) as i64 * FIR_Coefs[6] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[7] + buf_ptr[16]) as i64 * FIR_Coefs[7] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[8] + buf_ptr[15]) as i64 * FIR_Coefs[8] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[9] + buf_ptr[14]) as i64 * FIR_Coefs[9] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[10] + buf_ptr[13]) as i64 * FIR_Coefs[10] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[11] + buf_ptr[12]) as i64 * FIR_Coefs[11] as i64) >> 16) as i32; + + out[0] = (if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) as i16; + out = &mut out[1..]; + + index_Q16 += index_increment_Q16; + } + } + RESAMPLER_DOWN_ORDER_FIR2 => { + let mut index_Q16 = 0; + while index_Q16 < max_index_Q16 { + /* Integer part gives pointer to buffered input */ + let buf_ptr = &buf[(index_Q16 >> 16) as usize..]; + + let mut res_Q6 = + (((buf_ptr[0] + buf_ptr[35]) as i64 * FIR_Coefs[0] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[1] + buf_ptr[34]) as i64 * FIR_Coefs[1] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[2] + buf_ptr[33]) as i64 * FIR_Coefs[2] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[3] + buf_ptr[32]) as i64 * FIR_Coefs[3] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[4] + buf_ptr[31]) as i64 * FIR_Coefs[4] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[5] + buf_ptr[30]) as i64 * FIR_Coefs[5] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[6] + buf_ptr[29]) as i64 * FIR_Coefs[6] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[7] + buf_ptr[28]) as i64 * FIR_Coefs[7] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[8] + buf_ptr[27]) as i64 * FIR_Coefs[8] as i64) >> 16) as i32; + res_Q6 += (((buf_ptr[9] + buf_ptr[26]) as i64 * FIR_Coefs[9] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[10] + buf_ptr[25]) as i64 * FIR_Coefs[10] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[11] + buf_ptr[24]) as i64 * FIR_Coefs[11] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[12] + buf_ptr[23]) as i64 * FIR_Coefs[12] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[13] + buf_ptr[22]) as i64 * FIR_Coefs[13] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[14] + buf_ptr[21]) as i64 * FIR_Coefs[14] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[15] + buf_ptr[20]) as i64 * FIR_Coefs[15] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[16] + buf_ptr[19]) as i64 * FIR_Coefs[16] as i64) >> 16) as i32; + res_Q6 += + (((buf_ptr[17] + buf_ptr[18]) as i64 * FIR_Coefs[17] as i64) >> 16) as i32; + + out[0] = (if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 6 == 1 { + (res_Q6 >> 1) + (res_Q6 & 1) + } else { + (res_Q6 >> 6 - 1) + 1 >> 1 + }) as i16; + out = &mut out[1..]; + + index_Q16 += index_increment_Q16; + } + } + _ => unreachable!(), + } + + out +} + +pub(super) fn silk_resampler_private_down_FIR( + resampler_params: &ResamplerParams, + params: &ResamplerDownFirParams, + state: &mut ResamplerDownFirState, + mut out: &mut [i16], + mut in_0: &[i16], +) { + let mut nSamplesIn: usize = 0; + + let mut buf: Vec = + ::std::vec::from_elem(0, resampler_params.batch_size + params.fir_order); + + buf[..params.fir_order].copy_from_slice(&state.fir_state[..params.fir_order]); + + let index_increment_Q16 = resampler_params.inv_ratio_q16; + loop { + nSamplesIn = in_0.len().min(resampler_params.batch_size); + silk_resampler_private_AR2( + &mut state.ar2_state, + &mut buf[params.fir_order..][..nSamplesIn], + &in_0[..nSamplesIn], + ¶ms.coefs[..2], + ); + let max_index_Q16 = ((nSamplesIn as u32) << 16) as i32; + out = silk_resampler_private_down_FIR_INTERPOL( + out, + &buf, + ¶ms.coefs[2..], + params.fir_order, + params.fir_fracs, + max_index_Q16, + index_increment_Q16, + ); + in_0 = &in_0[nSamplesIn..]; + if in_0.is_empty() { + break; + } + + buf.copy_within(nSamplesIn..nSamplesIn + params.fir_order, 0); + } + state.fir_state[..params.fir_order] + .copy_from_slice(&buf[nSamplesIn..nSamplesIn + params.fir_order]); +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/iir_fir.rs b/vendor/unsafe-libopus/src/silk/resampler/iir_fir.rs new file mode 100644 index 00000000..61b01aa9 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/iir_fir.rs @@ -0,0 +1,112 @@ +#![forbid(unsafe_code)] + +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int16_MIN: i32 = i16::MIN as i32; +} +use crate::silk::resampler::ResamplerParams; + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +use super::rom::{silk_resampler_frac_FIR_12, RESAMPLER_ORDER_FIR_12}; +use super::up2_hq::{silk_resampler_private_up2_HQ, ResamplerUp2HqState}; + +#[derive(Default, Copy, Clone)] +pub struct ResamplerIirFirState { + up2_HQ: ResamplerUp2HqState, + fir_state: [i16; RESAMPLER_ORDER_FIR_12], +} + +#[inline] +fn silk_resampler_private_IIR_FIR_INTERPOL<'a>( + mut out: &'a mut [i16], + buf: &[i16], + max_index_Q16: i32, + index_increment_Q16: i32, +) -> &'a mut [i16] { + let mut res_Q15: i32 = 0; + + /* Interpolate upsampled signal and store in output array */ + let mut index_Q16 = 0; + while index_Q16 < max_index_Q16 { + let table_index = ((index_Q16 & 0xffff) as i64 * 12 as i64 >> 16) as usize; + let buf_ptr = &buf[(index_Q16 >> 16) as usize..][..8]; + + res_Q15 = buf_ptr[0] as i32 * silk_resampler_frac_FIR_12[table_index][0] as i32; + res_Q15 += buf_ptr[1] as i32 * silk_resampler_frac_FIR_12[table_index][1] as i32; + res_Q15 += buf_ptr[2] as i32 * silk_resampler_frac_FIR_12[table_index][2] as i32; + res_Q15 += buf_ptr[3] as i32 * silk_resampler_frac_FIR_12[table_index][3] as i32; + res_Q15 += buf_ptr[4] as i32 * silk_resampler_frac_FIR_12[11 - table_index][3] as i32; + res_Q15 += buf_ptr[5] as i32 * silk_resampler_frac_FIR_12[11 - table_index][2] as i32; + res_Q15 += buf_ptr[6] as i32 * silk_resampler_frac_FIR_12[11 - table_index][1] as i32; + res_Q15 += buf_ptr[7] as i32 * silk_resampler_frac_FIR_12[11 - table_index][0] as i32; + + out[0] = (if (if 15 == 1 { + (res_Q15 >> 1) + (res_Q15 & 1) + } else { + (res_Q15 >> 15 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 15 == 1 { + (res_Q15 >> 1) + (res_Q15 & 1) + } else { + (res_Q15 >> 15 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 15 == 1 { + (res_Q15 >> 1) + (res_Q15 & 1) + } else { + (res_Q15 >> 15 - 1) + 1 >> 1 + }) as i16; + + out = &mut out[1..]; + + index_Q16 += index_increment_Q16; + } + + out +} + +/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ +pub(super) fn silk_resampler_private_IIR_FIR( + resampler_params: &ResamplerParams, + state: &mut ResamplerIirFirState, + mut out: &mut [i16], + mut in_0: &[i16], +) { + let mut nSamplesIn: usize = 0; + let mut max_index_Q16: i32 = 0; + let mut buf: Vec = ::std::vec::from_elem(0, 2 * resampler_params.batch_size + 8); + + /* Copy buffered samples to start of buffer */ + buf[0..RESAMPLER_ORDER_FIR_12].copy_from_slice(&state.fir_state); + + /* Iterate over blocks of frameSizeIn input samples */ + let index_increment_Q16 = resampler_params.inv_ratio_q16; + loop { + nSamplesIn = in_0.len().min(resampler_params.batch_size); + silk_resampler_private_up2_HQ( + &mut state.up2_HQ, + &mut buf[RESAMPLER_ORDER_FIR_12..][..nSamplesIn * 2], + &in_0[..nSamplesIn], + ); + max_index_Q16 = ((nSamplesIn as u32) << (16 + 1)) as i32; /* + 1 because 2x upsampling */ + out = + silk_resampler_private_IIR_FIR_INTERPOL(out, &buf, max_index_Q16, index_increment_Q16); + in_0 = &in_0[nSamplesIn..]; + + if in_0.is_empty() { + break; + } + + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + buf.copy_within(nSamplesIn * 2..nSamplesIn * 2 + RESAMPLER_ORDER_FIR_12, 0); + } + + /* Copy last part of filtered signal to the state for the next call */ + state + .fir_state + .copy_from_slice(&buf[nSamplesIn * 2..][..RESAMPLER_ORDER_FIR_12]); +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/mod.rs b/vendor/unsafe-libopus/src/silk/resampler/mod.rs new file mode 100644 index 00000000..2370474c --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/mod.rs @@ -0,0 +1,275 @@ +#![forbid(unsafe_code)] + +mod ar2; +mod down_fir; +mod iir_fir; +mod rom; +mod up2_hq; + +mod down2; +mod down2_3; + +use down_fir::{silk_resampler_private_down_FIR, ResamplerDownFirParams, ResamplerDownFirState}; +use iir_fir::{silk_resampler_private_IIR_FIR, ResamplerIirFirState}; +use rom::{ + silk_Resampler_1_2_COEFS, silk_Resampler_1_3_COEFS, silk_Resampler_1_4_COEFS, + silk_Resampler_1_6_COEFS, silk_Resampler_2_3_COEFS, silk_Resampler_3_4_COEFS, + RESAMPLER_DOWN_ORDER_FIR0, RESAMPLER_DOWN_ORDER_FIR1, RESAMPLER_DOWN_ORDER_FIR2, +}; +use std::cmp::Ordering; +use up2_hq::{silk_resampler_private_up2_HQ, ResamplerUp2HqState}; + +pub use down2::silk_resampler_down2; +pub use down2_3::silk_resampler_down2_3; + +const RESAMPLER_MAX_BATCH_SIZE_MS: i32 = 10; +const RESAMPLER_MAX_FS_KHZ: usize = 48; +const RESAMPLER_MAX_BATCH_SIZE_IN: usize = + RESAMPLER_MAX_BATCH_SIZE_MS as usize * RESAMPLER_MAX_FS_KHZ; + +/* + * Matrix of resampling methods used: + * Fs_out (kHz) + * 8 12 16 24 48 + * + * 8 C UF U UF UF + * 12 AF C UF U UF + * Fs_in (kHz) 16 D AF C UF UF + * 24 AF D AF C U + * 48 AF AF AF D C + * + * C -> Copy (no resampling) + * D -> Allpass-based 2x downsampling + * U -> Allpass-based 2x upsampling + * UF -> Allpass-based 2x upsampling followed by FIR interpolation + * AF -> AR2 filter followed by FIR interpolation + */ + +#[rustfmt::skip] +static delay_matrix_enc: [[i8; 3]; 5] = [ + /* in \ out 8 12 16 */ + /* 8 */ [ 6, 0, 3 ], + /* 12 */ [ 0, 7, 3 ], + /* 16 */ [ 0, 1, 10 ], + /* 24 */ [ 0, 2, 6 ], + /* 48 */ [ 18, 10, 12 ], +]; +#[rustfmt::skip] +static delay_matrix_dec: [[i8; 5]; 3] = [ + /* in \ out 8 12 16 24 48 */ + /* 8 */ [ 4, 0, 2, 0, 0 ], + /* 12 */ [ 0, 9, 4, 7, 4 ], + /* 16 */ [ 0, 3, 12, 7, 7 ], +]; + +/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */ +fn rate_id(r: i32) -> usize { + match r { + 8000 => 0, + 12000 => 1, + 16000 => 2, + 24000 => 3, + 48000 => 4, + _ => unreachable!("unsupported sampling rate"), + } +} + +const SILK_RESAMPLER_MAX_FIR_ORDER: usize = 36; + +#[derive(Copy, Clone)] +pub struct ResamplerState { + params: ResamplerParams, + mode: ResamplerMode, + delay_buf: [i16; 48], +} + +#[derive(Copy, Clone)] +struct ResamplerParams { + pub batch_size: usize, + pub inv_ratio_q16: i32, + pub fs_in_khz: usize, + pub fs_out_khz: usize, + pub input_delay: usize, +} + +/// Includes the resampler mode, as well as the necessary params and state +#[derive(Copy, Clone)] +enum ResamplerMode { + Copy, + Up2Hq(ResamplerUp2HqState), + IirFir(ResamplerIirFirState), + DownFir(ResamplerDownFirParams, ResamplerDownFirState), +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub union sFIR_union { + pub i32_0: [i32; SILK_RESAMPLER_MAX_FIR_ORDER], + pub i16_0: [i16; SILK_RESAMPLER_MAX_FIR_ORDER], +} + +pub fn silk_resampler_init(Fs_Hz_in: i32, Fs_Hz_out: i32, forEnc: i32) -> ResamplerState { + let inputDelay = if forEnc != 0 { + if !matches!(Fs_Hz_in, 8000 | 12000 | 16000 | 24000 | 48000) + || !matches!(Fs_Hz_out, 8000 | 12000 | 16000) + { + // see comments in `[unsafe_libopus::silk::check_control_input]` + // TODO: we should probably make this function return a Result.. + panic!("libopus: assert(0) called"); + // return -1; + } + + delay_matrix_enc[rate_id(Fs_Hz_in)][rate_id(Fs_Hz_out)] as i32 + } else { + if !matches!(Fs_Hz_in, 8000 | 12000 | 16000) + || !matches!(Fs_Hz_out, 8000 | 12000 | 16000 | 24000 | 48000) + { + // see comments in `[unsafe_libopus::silk::check_control_input]` + // TODO: we should probably make this function return a Result.. + panic!("libopus: assert(0) called"); + // return -1; + } + + delay_matrix_dec[rate_id(Fs_Hz_in)][rate_id(Fs_Hz_out)] as i32 + }; + + let Fs_in_kHz = Fs_Hz_in / 1000; + let Fs_out_kHz = Fs_Hz_out / 1000; + let batchSize = Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS; + + let mut up2x = 0; + let mode = match Fs_Hz_out.cmp(&Fs_Hz_in) { + Ordering::Greater => { + // Upsample + // Fs_out : Fs_in = 2 : 1 + if Fs_Hz_out == Fs_Hz_in * 2 { + // Special case: directly use 2x upsampler + ResamplerMode::Up2Hq(ResamplerUp2HqState::default()) + } else { + // Default resampler + up2x = 1; + ResamplerMode::IirFir(ResamplerIirFirState::default()) + } + } + Ordering::Less => { + // downsample + let params = if Fs_Hz_out * 4 == Fs_Hz_in * 3 { + // Fs_out : Fs_in = 3 : 4 + ResamplerDownFirParams { + fir_order: RESAMPLER_DOWN_ORDER_FIR0, + fir_fracs: 3, + coefs: &silk_Resampler_3_4_COEFS, + } + } else if Fs_Hz_out * 3 == Fs_Hz_in * 2 { + // Fs_out : Fs_in = 2 : 3 + ResamplerDownFirParams { + fir_order: RESAMPLER_DOWN_ORDER_FIR0, + fir_fracs: 2, + coefs: &silk_Resampler_2_3_COEFS, + } + } else if Fs_Hz_out * 2 == Fs_Hz_in { + // Fs_out : Fs_in = 1 : 2 + ResamplerDownFirParams { + fir_order: RESAMPLER_DOWN_ORDER_FIR1, + fir_fracs: 1, + coefs: &silk_Resampler_1_2_COEFS, + } + } else if Fs_Hz_out * 3 == Fs_Hz_in { + // Fs_out : Fs_in = 1 : 3 + ResamplerDownFirParams { + fir_order: RESAMPLER_DOWN_ORDER_FIR2, + fir_fracs: 1, + coefs: &silk_Resampler_1_3_COEFS, + } + } else if Fs_Hz_out * 4 == Fs_Hz_in { + // Fs_out : Fs_in = 1 : 4 + ResamplerDownFirParams { + fir_order: RESAMPLER_DOWN_ORDER_FIR2, + fir_fracs: 1, + coefs: &silk_Resampler_1_4_COEFS, + } + } else if Fs_Hz_out * 6 == Fs_Hz_in { + // Fs_out : Fs_in = 1 : 6 + ResamplerDownFirParams { + fir_order: RESAMPLER_DOWN_ORDER_FIR2, + fir_fracs: 1, + coefs: &silk_Resampler_1_6_COEFS, + } + } else { + unreachable!("Unsupported resampling ratio: {} : {}", Fs_Hz_out, Fs_Hz_in); + }; + + ResamplerMode::DownFir(params, ResamplerDownFirState::default()) + } + Ordering::Equal => ResamplerMode::Copy, + }; + + /* Ratio of input/output samples */ + let mut invRatio_Q16 = + (((((Fs_Hz_in as u32) << (14 + up2x)) as i32 / Fs_Hz_out) as u32) << 2) as i32; + /* Make sure the ratio is rounded up */ + while (((invRatio_Q16 as i64 * Fs_Hz_out as i64) >> 16) as i32) + < ((Fs_Hz_in as u32) << up2x) as i32 + { + invRatio_Q16 += 1; + } + + let params = ResamplerParams { + batch_size: batchSize as usize, + inv_ratio_q16: invRatio_Q16, + fs_in_khz: Fs_in_kHz as usize, + fs_out_khz: Fs_out_kHz as usize, + input_delay: inputDelay as usize, + }; + + ResamplerState { + params, + mode, + delay_buf: [0; 48], + } +} + +/* Resampler: convert from one sampling rate to another */ +/* Input and output sampling rate are at most 48000 Hz */ +pub fn silk_resampler(S: &mut ResamplerState, out: &mut [i16], in_0: &[i16]) -> i32 { + /* Need at least 1 ms of input data */ + assert!(in_0.len() >= S.params.fs_in_khz); + /* Delay can't exceed the 1 ms of buffering */ + assert!(S.params.input_delay <= S.params.fs_in_khz); + + let nSamples = S.params.fs_in_khz - S.params.input_delay; + + /* Copy to delay buffer */ + S.delay_buf[S.params.input_delay..][..nSamples].copy_from_slice(&in_0[..nSamples]); + + let delay_in = &S.delay_buf[..S.params.fs_in_khz]; + let rest_in = &in_0[nSamples..][..in_0.len() - S.params.fs_in_khz]; + let (delay_out, rest_out) = out.split_at_mut(S.params.fs_out_khz); + + // ensure we have exactly the right amount of space in the out buffer + let rest_out = &mut rest_out[..rest_in.len() * S.params.fs_out_khz / S.params.fs_in_khz]; + + match &mut S.mode { + ResamplerMode::Up2Hq(state) => { + silk_resampler_private_up2_HQ(state, delay_out, delay_in); + silk_resampler_private_up2_HQ(state, rest_out, rest_in); + } + ResamplerMode::IirFir(state) => { + silk_resampler_private_IIR_FIR(&S.params, state, delay_out, delay_in); + silk_resampler_private_IIR_FIR(&S.params, state, rest_out, rest_in); + } + ResamplerMode::DownFir(ref params, state) => { + silk_resampler_private_down_FIR(&S.params, params, state, delay_out, delay_in); + silk_resampler_private_down_FIR(&S.params, params, state, rest_out, rest_in); + } + ResamplerMode::Copy => { + delay_out.copy_from_slice(delay_in); + rest_out.copy_from_slice(rest_in); + } + } + + /* Copy to delay buffer */ + S.delay_buf[..S.params.input_delay].copy_from_slice(&in_0[in_0.len() - S.params.input_delay..]); + + 0 +} diff --git a/vendor/unsafe-libopus/src/silk/resampler/rom.rs b/vendor/unsafe-libopus/src/silk/resampler/rom.rs new file mode 100644 index 00000000..6e5ab0e3 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/rom.rs @@ -0,0 +1,59 @@ +pub const RESAMPLER_DOWN_ORDER_FIR2: usize = 36; +pub const RESAMPLER_DOWN_ORDER_FIR1: usize = 24; +pub const RESAMPLER_DOWN_ORDER_FIR0: usize = 18; +pub const RESAMPLER_ORDER_FIR_12: usize = 8; + +/* Tables for 2x downsampler */ +pub const silk_resampler_down2_0: i16 = 9872; +pub const silk_resampler_down2_1: i16 = (39809 - 65536) as i16; + +/* Tables for 2x upsampler, high quality */ +pub const silk_resampler_up2_hq_0: [i16; 3] = [1746, 14986, (39083 - 65536) as i16]; +pub const silk_resampler_up2_hq_1: [i16; 3] = [6854, 25769, (55542 - 65536) as i16]; + +/* Matlab code for the notch filter coefficients: */ +/* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */ +/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ +/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; */ + +/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ + +pub static silk_Resampler_3_4_COEFS: [i16; 29] = [ + -20694, -13867, -49, 64, 17, -157, 353, -496, 163, 11047, 22205, -39, 6, 91, -170, 186, 23, + -896, 6336, 19928, -19, -36, 102, -89, -24, 328, -951, 2568, 15909, +]; +pub static silk_Resampler_2_3_COEFS: [i16; 20] = [ + -14457, -14019, 64, 128, -122, 36, 310, -768, 584, 9267, 17733, 12, 128, 18, -142, 288, -117, + -865, 4123, 14459, +]; +pub static silk_Resampler_1_2_COEFS: [i16; 14] = [ + 616, -14323, -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, +]; +pub static silk_Resampler_1_3_COEFS: [i16; 20] = [ + 16102, -15162, -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, + 3271, +]; +pub static silk_Resampler_1_4_COEFS: [i16; 20] = [ + 22500, -15099, 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, + 1464, +]; +pub static silk_Resampler_1_6_COEFS: [i16; 20] = [ + 27540, -15257, 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, +]; +pub static silk_Resampler_2_3_COEFS_LQ: [i16; 6] = [-2797, -6507, 4697, 10739, 1567, 8276]; + +/* Table with interplation fractions of 1/24, 3/24, ..., 23/24 */ +pub static silk_resampler_frac_FIR_12: [[i16; 4]; 12] = [ + [189, -600, 617, 30567], + [117, -159, -1070, 29704], + [52, 221, -2392, 28276], + [-4, 529, -3350, 26341], + [-48, 758, -3956, 23973], + [-80, 905, -4235, 21254], + [-99, 972, -4222, 18278], + [-107, 967, -3957, 15143], + [-103, 896, -3487, 11950], + [-91, 773, -2865, 8798], + [-71, 611, -2143, 5784], + [-46, 425, -1375, 2996], +]; diff --git a/vendor/unsafe-libopus/src/silk/resampler/up2_hq.rs b/vendor/unsafe-libopus/src/silk/resampler/up2_hq.rs new file mode 100644 index 00000000..a31c13ab --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/resampler/up2_hq.rs @@ -0,0 +1,110 @@ +use super::rom::{silk_resampler_up2_hq_0, silk_resampler_up2_hq_1}; + +pub mod typedef_h { + pub const silk_int16_MAX: i32 = i16::MAX as i32; + pub const silk_int16_MIN: i32 = i16::MIN as i32; +} + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; + +#[derive(Default, Copy, Clone)] +pub struct ResamplerUp2HqState { + iir_state: [i32; 6], +} + +/* Upsample by a factor 2, high quality */ +/* Uses 2nd order allpass filters for the 2x upsampling, followed by a */ +/* notch filter just above Nyquist. */ +pub fn silk_resampler_private_up2_HQ( + state: &mut ResamplerUp2HqState, + out: &mut [i16], + in_0: &[i16], +) { + assert_eq!(out.len(), 2 * in_0.len()); + + let s = &mut state.iir_state; + + /* Internal variables and state are in Q10 format */ + for k in 0..in_0.len() { + /* Convert to Q10 */ + let in32 = ((in_0[k] as i32 as u32) << 10) as i32; + + /* First all-pass section for even output sample */ + let Y = in32 - s[0]; + let X = ((Y as i64 * silk_resampler_up2_hq_0[0] as i64) >> 16) as i32; + let out32_1 = s[0] + X; + s[0] = in32 + X; + + /* Second all-pass section for even output sample */ + let Y = out32_1 - s[1]; + let X = ((Y as i64 * silk_resampler_up2_hq_0[1] as i64) >> 16) as i32; + let out32_2 = s[1] + X; + s[1] = out32_1 + X; + + /* Third all-pass section for even output sample */ + let Y = out32_2 - s[2]; + let X = (Y as i64 + ((Y as i64 * silk_resampler_up2_hq_0[2] as i64) >> 16)) as i32; + let out32_1 = s[2] + X; + s[2] = out32_2 + X; + + /* Apply gain in Q15, convert back to int16 and store to output */ + out[2 * k] = (if (if 10 == 1 { + (out32_1 >> 1) + (out32_1 & 1) + } else { + (out32_1 >> 10 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 10 == 1 { + (out32_1 >> 1) + (out32_1 & 1) + } else { + (out32_1 >> 10 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 10 == 1 { + (out32_1 >> 1) + (out32_1 & 1) + } else { + (out32_1 >> 10 - 1) + 1 >> 1 + }) as i16; + + /* First all-pass section for odd output sample */ + let Y = in32 - s[3]; + let X = ((Y as i64 * silk_resampler_up2_hq_1[0] as i64) >> 16) as i32; + let out32_1 = s[3] + X; + s[3] = in32 + X; + + /* second all-pass section for odd output sample */ + let Y = out32_1 - s[4]; + let X = ((Y as i64 * silk_resampler_up2_hq_1[1] as i64) >> 16) as i32; + let out32_2 = s[4] + X; + s[4] = out32_1 + X; + + /* Third all-pass section for odd output sample */ + let Y = out32_2 - s[5]; + let X = (Y as i64 + ((Y as i64 * silk_resampler_up2_hq_1[2] as i64) >> 16)) as i32; + let out32_1 = s[5] + X; + s[5] = out32_2 + X; + + /* Apply gain in Q15, convert back to int16 and store to output */ + out[2 * k + 1] = (if (if 10 == 1 { + (out32_1 >> 1) + (out32_1 & 1) + } else { + (out32_1 >> 10 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 10 == 1 { + (out32_1 >> 1) + (out32_1 & 1) + } else { + (out32_1 >> 10 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 10 == 1 { + (out32_1 >> 1) + (out32_1 & 1) + } else { + (out32_1 >> 10 - 1) + 1 >> 1 + }) as i16; + } +} diff --git a/vendor/unsafe-libopus/src/silk/shell_coder.rs b/vendor/unsafe-libopus/src/silk/shell_coder.rs new file mode 100644 index 00000000..61568880 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/shell_coder.rs @@ -0,0 +1,179 @@ +#![forbid(unsafe_code)] + +//! shell coder; pulse-subframe length is hardcoded + +use crate::celt::entdec::{ec_dec, ec_dec_icdf}; +use crate::celt::entenc::{ec_enc, ec_enc_icdf}; +use crate::silk::define::SHELL_CODEC_FRAME_LENGTH; +use crate::silk::tables_pulses_per_block::{ + silk_shell_code_table0, silk_shell_code_table1, silk_shell_code_table2, silk_shell_code_table3, + silk_shell_code_table_offsets, +}; + +#[inline] +fn combine_pulses(out: &mut [i32], in_: &[i32]) { + assert_eq!(out.len() * 2, in_.len()); + + for (out, in_) in out.iter_mut().zip(in_.chunks_exact(2)) { + *out = in_.iter().sum::(); + } +} + +#[inline] +fn encode_split(psRangeEnc: &mut ec_enc, p_child1: i32, p: i32, shell_table: &[u8]) { + if p > 0 { + ec_enc_icdf( + psRangeEnc, + p_child1, + &shell_table[silk_shell_code_table_offsets[p as usize] as usize..], + 8, + ); + } +} + +#[inline] +fn decode_split(p_child: &mut [i16], psRangeDec: &mut ec_dec, p: i32, shell_table: &[u8]) { + assert_eq!(p_child.len(), 2); + + if p > 0 { + p_child[0] = ec_dec_icdf( + psRangeDec, + &shell_table[silk_shell_code_table_offsets[p as usize] as usize..], + 8, + ) as i16; + p_child[1] = (p - p_child[0] as i32) as i16; + } else { + p_child[0] = 0; + p_child[1] = 0; + }; +} + +/// Shell encoder, operates on one shell code frame of 16 pulses +pub fn silk_shell_encoder(psRangeEnc: &mut ec_enc, pulses0: &[i32]) { + let mut pulses1: [i32; 8] = [0; 8]; + let mut pulses2: [i32; 4] = [0; 4]; + let mut pulses3: [i32; 2] = [0; 2]; + let mut pulses4: [i32; 1] = [0; 1]; + + assert_eq!(pulses0.len(), SHELL_CODEC_FRAME_LENGTH as usize); + assert_eq!(SHELL_CODEC_FRAME_LENGTH, 16); + + combine_pulses(&mut pulses1, pulses0); + combine_pulses(&mut pulses2, &pulses1); + combine_pulses(&mut pulses3, &pulses2); + combine_pulses(&mut pulses4, &pulses3); + encode_split(psRangeEnc, pulses3[0], pulses4[0], &silk_shell_code_table3); + encode_split(psRangeEnc, pulses2[0], pulses3[0], &silk_shell_code_table2); + encode_split(psRangeEnc, pulses1[0], pulses2[0], &silk_shell_code_table1); + encode_split(psRangeEnc, pulses0[0], pulses1[0], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses0[2], pulses1[1], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses1[2], pulses2[1], &silk_shell_code_table1); + encode_split(psRangeEnc, pulses0[4], pulses1[2], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses0[6], pulses1[3], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses2[2], pulses3[1], &silk_shell_code_table2); + encode_split(psRangeEnc, pulses1[4], pulses2[2], &silk_shell_code_table1); + encode_split(psRangeEnc, pulses0[8], pulses1[4], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses0[10], pulses1[5], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses1[6], pulses2[3], &silk_shell_code_table1); + encode_split(psRangeEnc, pulses0[12], pulses1[6], &silk_shell_code_table0); + encode_split(psRangeEnc, pulses0[14], pulses1[7], &silk_shell_code_table0); +} + +pub fn silk_shell_decoder(pulses0: &mut [i16], psRangeDec: &mut ec_dec, pulses4: i32) { + assert_eq!(pulses0.len(), SHELL_CODEC_FRAME_LENGTH as usize); + assert_eq!(SHELL_CODEC_FRAME_LENGTH, 16); + + let mut pulses3: [i16; 2] = [0; 2]; + let mut pulses2: [i16; 4] = [0; 4]; + let mut pulses1: [i16; 8] = [0; 8]; + decode_split( + &mut pulses3[0..=1], + psRangeDec, + pulses4, + &silk_shell_code_table3, + ); + decode_split( + &mut pulses2[0..=1], + psRangeDec, + pulses3[0] as i32, + &silk_shell_code_table2, + ); + decode_split( + &mut pulses1[0..=1], + psRangeDec, + pulses2[0] as i32, + &silk_shell_code_table1, + ); + decode_split( + &mut pulses0[0..=1], + psRangeDec, + pulses1[0] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses0[2..=3], + psRangeDec, + pulses1[1] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses1[2..=3], + psRangeDec, + pulses2[1] as i32, + &silk_shell_code_table1, + ); + decode_split( + &mut pulses0[4..=5], + psRangeDec, + pulses1[2] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses0[6..=7], + psRangeDec, + pulses1[3] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses2[2..=3], + psRangeDec, + pulses3[1] as i32, + &silk_shell_code_table2, + ); + decode_split( + &mut pulses1[4..=5], + psRangeDec, + pulses2[2] as i32, + &silk_shell_code_table1, + ); + decode_split( + &mut pulses0[8..=9], + psRangeDec, + pulses1[4] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses0[10..=11], + psRangeDec, + pulses1[5] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses1[6..=7], + psRangeDec, + pulses2[3] as i32, + &silk_shell_code_table1, + ); + decode_split( + &mut pulses0[12..=13], + psRangeDec, + pulses1[6] as i32, + &silk_shell_code_table0, + ); + decode_split( + &mut pulses0[14..=15], + psRangeDec, + pulses1[7] as i32, + &silk_shell_code_table0, + ); +} diff --git a/vendor/unsafe-libopus/src/silk/sigm_Q15.rs b/vendor/unsafe-libopus/src/silk/sigm_Q15.rs new file mode 100644 index 00000000..bb3261a0 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/sigm_Q15.rs @@ -0,0 +1,22 @@ +static mut sigm_LUT_slope_Q10: [i32; 6] = [237, 153, 73, 30, 12, 7]; +static mut sigm_LUT_pos_Q15: [i32; 6] = [16384, 23955, 28861, 31213, 32178, 32548]; +static mut sigm_LUT_neg_Q15: [i32; 6] = [16384, 8812, 3906, 1554, 589, 219]; +pub unsafe fn silk_sigm_Q15(mut in_Q5: i32) -> i32 { + let mut ind: i32 = 0; + if in_Q5 < 0 { + in_Q5 = -in_Q5; + if in_Q5 >= 6 * 32 { + return 0; + } else { + ind = in_Q5 >> 5; + return sigm_LUT_neg_Q15[ind as usize] + - sigm_LUT_slope_Q10[ind as usize] as i16 as i32 * (in_Q5 & 0x1f) as i16 as i32; + } + } else if in_Q5 >= 6 * 32 { + return 32767; + } else { + ind = in_Q5 >> 5; + return sigm_LUT_pos_Q15[ind as usize] + + sigm_LUT_slope_Q10[ind as usize] as i16 as i32 * (in_Q5 & 0x1f) as i16 as i32; + }; +} diff --git a/vendor/unsafe-libopus/src/silk/sort.rs b/vendor/unsafe-libopus/src/silk/sort.rs new file mode 100644 index 00000000..4a35716b --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/sort.rs @@ -0,0 +1,51 @@ +pub unsafe fn silk_insertion_sort_increasing(a: *mut i32, idx: *mut i32, L: i32, K: i32) { + let mut value: i32 = 0; + let mut i: i32 = 0; + let mut j: i32 = 0; + assert!(K > 0); + assert!(L > 0); + assert!(L >= K); + i = 0; + while i < K { + *idx.offset(i as isize) = i; + i += 1; + } + i = 1; + while i < K { + value = *a.offset(i as isize); + j = i - 1; + while j >= 0 && value < *a.offset(j as isize) { + *a.offset((j + 1) as isize) = *a.offset(j as isize); + *idx.offset((j + 1) as isize) = *idx.offset(j as isize); + j -= 1; + } + *a.offset((j + 1) as isize) = value; + *idx.offset((j + 1) as isize) = i; + i += 1; + } + i = K; + while i < L { + value = *a.offset(i as isize); + if value < *a.offset((K - 1) as isize) { + j = K - 2; + while j >= 0 && value < *a.offset(j as isize) { + *a.offset((j + 1) as isize) = *a.offset(j as isize); + *idx.offset((j + 1) as isize) = *idx.offset(j as isize); + j -= 1; + } + *a.offset((j + 1) as isize) = value; + *idx.offset((j + 1) as isize) = i; + } + i += 1; + } +} + +pub fn silk_insertion_sort_increasing_all_values_int16(a: &mut [i16]) { + for i in 1..a.len() { + let mut j = i; + while j > 0 && a[j] < a[j - 1] { + a.swap(j, j - 1); + j -= 1; + } + } +} diff --git a/vendor/unsafe-libopus/src/silk/stereo_LR_to_MS.rs b/vendor/unsafe-libopus/src/silk/stereo_LR_to_MS.rs new file mode 100644 index 00000000..fe63f30a --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/stereo_LR_to_MS.rs @@ -0,0 +1,407 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +use crate::externs::memcpy; +use crate::silk::define::{LA_SHAPE_MS, STEREO_INTERP_LEN_MS}; +use crate::silk::stereo_find_predictor::silk_stereo_find_predictor; +use crate::silk::stereo_quant_pred::silk_stereo_quant_pred; +use crate::silk::structs::stereo_enc_state; +use crate::silk::Inlines::silk_DIV32_varQ; +use crate::silk::SigProc_FIX::silk_max_int; + +pub unsafe fn silk_stereo_LR_to_MS( + state: *mut stereo_enc_state, + x1: *mut i16, + x2: *mut i16, + ix: *mut [i8; 3], + mid_only_flag: *mut i8, + mid_side_rates_bps: *mut i32, + mut total_rate_bps: i32, + prev_speech_act_Q8: i32, + toMono: i32, + fs_kHz: i32, + frame_length: i32, +) { + let mut n: i32 = 0; + let mut is10msFrame: i32 = 0; + let mut denom_Q16: i32 = 0; + let mut delta0_Q13: i32 = 0; + let mut delta1_Q13: i32 = 0; + let mut sum: i32 = 0; + let mut diff: i32 = 0; + let mut smooth_coef_Q16: i32 = 0; + let mut pred_Q13: [i32; 2] = [0; 2]; + let mut pred0_Q13: i32 = 0; + let mut pred1_Q13: i32 = 0; + let mut LP_ratio_Q14: i32 = 0; + let mut HP_ratio_Q14: i32 = 0; + let mut frac_Q16: i32 = 0; + let mut frac_3_Q16: i32 = 0; + let mut min_mid_rate_bps: i32 = 0; + let mut width_Q14: i32 = 0; + let mut w_Q24: i32 = 0; + let mut deltaw_Q24: i32 = 0; + let mid: *mut i16 = &mut *x1.offset(-(2) as isize) as *mut i16; + let vla = (frame_length + 2) as usize; + let mut side: Vec = ::std::vec::from_elem(0, vla); + n = 0; + while n < frame_length + 2 { + sum = *x1.offset((n - 2) as isize) as i32 + *x2.offset((n - 2) as isize) as i32; + diff = *x1.offset((n - 2) as isize) as i32 - *x2.offset((n - 2) as isize) as i32; + *mid.offset(n as isize) = (if 1 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 1 - 1) + 1 >> 1 + }) as i16; + *side.as_mut_ptr().offset(n as isize) = (if (if 1 == 1 { + (diff >> 1) + (diff & 1) + } else { + (diff >> 1 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 1 == 1 { + (diff >> 1) + (diff & 1) + } else { + (diff >> 1 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 1 == 1 { + (diff >> 1) + (diff & 1) + } else { + (diff >> 1 - 1) + 1 >> 1 + }) as i16; + n += 1; + } + memcpy( + mid as *mut core::ffi::c_void, + ((*state).sMid).as_mut_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + side.as_mut_ptr() as *mut core::ffi::c_void, + ((*state).sSide).as_mut_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*state).sMid).as_mut_ptr() as *mut core::ffi::c_void, + &mut *mid.offset(frame_length as isize) as *mut i16 as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*state).sSide).as_mut_ptr() as *mut core::ffi::c_void, + &mut *side.as_mut_ptr().offset(frame_length as isize) as *mut i16 + as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + let vla_0 = frame_length as usize; + let mut LP_mid: Vec = ::std::vec::from_elem(0, vla_0); + let vla_1 = frame_length as usize; + let mut HP_mid: Vec = ::std::vec::from_elem(0, vla_1); + n = 0; + while n < frame_length { + sum = if 2 == 1 { + (*mid.offset(n as isize) as i32 + + *mid.offset((n + 2) as isize) as i32 + + ((*mid.offset((n + 1) as isize) as u32) << 1) as i32 + >> 1) + + (*mid.offset(n as isize) as i32 + + *mid.offset((n + 2) as isize) as i32 + + ((*mid.offset((n + 1) as isize) as u32) << 1) as i32 + & 1) + } else { + (*mid.offset(n as isize) as i32 + + *mid.offset((n + 2) as isize) as i32 + + ((*mid.offset((n + 1) as isize) as u32) << 1) as i32 + >> 2 - 1) + + 1 + >> 1 + }; + *LP_mid.as_mut_ptr().offset(n as isize) = sum as i16; + *HP_mid.as_mut_ptr().offset(n as isize) = + (*mid.offset((n + 1) as isize) as i32 - sum) as i16; + n += 1; + } + let vla_2 = frame_length as usize; + let mut LP_side: Vec = ::std::vec::from_elem(0, vla_2); + let vla_3 = frame_length as usize; + let mut HP_side: Vec = ::std::vec::from_elem(0, vla_3); + n = 0; + while n < frame_length { + sum = if 2 == 1 { + (*side.as_mut_ptr().offset(n as isize) as i32 + + *side.as_mut_ptr().offset((n + 2) as isize) as i32 + + ((*side.as_mut_ptr().offset((n + 1) as isize) as u32) << 1) as i32 + >> 1) + + (*side.as_mut_ptr().offset(n as isize) as i32 + + *side.as_mut_ptr().offset((n + 2) as isize) as i32 + + ((*side.as_mut_ptr().offset((n + 1) as isize) as u32) << 1) as i32 + & 1) + } else { + (*side.as_mut_ptr().offset(n as isize) as i32 + + *side.as_mut_ptr().offset((n + 2) as isize) as i32 + + ((*side.as_mut_ptr().offset((n + 1) as isize) as u32) << 1) as i32 + >> 2 - 1) + + 1 + >> 1 + }; + *LP_side.as_mut_ptr().offset(n as isize) = sum as i16; + *HP_side.as_mut_ptr().offset(n as isize) = + (*side.as_mut_ptr().offset((n + 1) as isize) as i32 - sum) as i16; + n += 1; + } + is10msFrame = (frame_length == 10 * fs_kHz) as i32; + smooth_coef_Q16 = if is10msFrame != 0 { + (0.01f64 / 2 as f64 * ((1) << 16) as f64 + 0.5f64) as i32 + } else { + (0.01f64 * ((1) << 16) as f64 + 0.5f64) as i32 + }; + smooth_coef_Q16 = ((prev_speech_act_Q8 as i16 as i32 * prev_speech_act_Q8 as i16 as i32) as i64 + * smooth_coef_Q16 as i16 as i64 + >> 16) as i32; + pred_Q13[0 as usize] = silk_stereo_find_predictor( + &mut LP_ratio_Q14, + LP_mid.as_mut_ptr() as *const i16, + LP_side.as_mut_ptr() as *const i16, + &mut *((*state).mid_side_amp_Q0).as_mut_ptr().offset(0 as isize), + frame_length, + smooth_coef_Q16, + ); + pred_Q13[1 as usize] = silk_stereo_find_predictor( + &mut HP_ratio_Q14, + HP_mid.as_mut_ptr() as *const i16, + HP_side.as_mut_ptr() as *const i16, + &mut *((*state).mid_side_amp_Q0).as_mut_ptr().offset(2 as isize), + frame_length, + smooth_coef_Q16, + ); + frac_Q16 = HP_ratio_Q14 + LP_ratio_Q14 as i16 as i32 * 3; + frac_Q16 = if frac_Q16 < ((1 * ((1) << 16)) as f64 + 0.5f64) as i32 { + frac_Q16 + } else { + ((1 * ((1) << 16)) as f64 + 0.5f64) as i32 + }; + total_rate_bps -= if is10msFrame != 0 { 1200 } else { 600 }; + if total_rate_bps < 1 { + total_rate_bps = 1; + } + min_mid_rate_bps = 2000 + fs_kHz as i16 as i32 * 600; + frac_3_Q16 = 3 * frac_Q16; + *mid_side_rates_bps.offset(0 as isize) = silk_DIV32_varQ( + total_rate_bps, + (((8 + 5) as i64 * ((1) << 16)) as f64 + 0.5f64) as i32 + frac_3_Q16, + 16 + 3, + ); + if *mid_side_rates_bps.offset(0 as isize) < min_mid_rate_bps { + *mid_side_rates_bps.offset(0 as isize) = min_mid_rate_bps; + *mid_side_rates_bps.offset(1 as isize) = + total_rate_bps - *mid_side_rates_bps.offset(0 as isize); + width_Q14 = silk_DIV32_varQ( + ((*mid_side_rates_bps.offset(1 as isize) as u32) << 1) as i32 - min_mid_rate_bps, + ((((1 * ((1) << 16)) as f64 + 0.5f64) as i32 + frac_3_Q16) as i64 + * min_mid_rate_bps as i16 as i64 + >> 16) as i32, + 14 + 2, + ); + width_Q14 = if 0 > ((1 * ((1) << 14)) as f64 + 0.5f64) as i32 { + if width_Q14 > 0 { + 0 + } else if width_Q14 < ((1 * ((1) << 14)) as f64 + 0.5f64) as i32 { + ((1 * ((1) << 14)) as f64 + 0.5f64) as i32 + } else { + width_Q14 + } + } else if width_Q14 > ((1 * ((1) << 14)) as f64 + 0.5f64) as i32 { + ((1 * ((1) << 14)) as f64 + 0.5f64) as i32 + } else if width_Q14 < 0 { + 0 + } else { + width_Q14 + }; + } else { + *mid_side_rates_bps.offset(1 as isize) = + total_rate_bps - *mid_side_rates_bps.offset(0 as isize); + width_Q14 = ((1 * ((1) << 14)) as f64 + 0.5f64) as i32; + } + (*state).smth_width_Q14 = ((*state).smth_width_Q14 as i64 + + ((width_Q14 - (*state).smth_width_Q14 as i32) as i64 * smooth_coef_Q16 as i16 as i64 + >> 16)) as i32 as i16; + *mid_only_flag = 0; + if toMono != 0 { + width_Q14 = 0; + pred_Q13[0 as usize] = 0; + pred_Q13[1 as usize] = 0; + silk_stereo_quant_pred(pred_Q13.as_mut_ptr(), ix); + } else if (*state).width_prev_Q14 as i32 == 0 + && (8 * total_rate_bps < 13 * min_mid_rate_bps + || ((frac_Q16 as i64 * (*state).smth_width_Q14 as i64 >> 16) as i32) + < (0.05f64 * ((1) << 14) as f64 + 0.5f64) as i32) + { + pred_Q13[0 as usize] = + (*state).smth_width_Q14 as i32 * pred_Q13[0 as usize] as i16 as i32 >> 14; + pred_Q13[1 as usize] = + (*state).smth_width_Q14 as i32 * pred_Q13[1 as usize] as i16 as i32 >> 14; + silk_stereo_quant_pred(pred_Q13.as_mut_ptr(), ix); + width_Q14 = 0; + pred_Q13[0 as usize] = 0; + pred_Q13[1 as usize] = 0; + *mid_side_rates_bps.offset(0 as isize) = total_rate_bps; + *mid_side_rates_bps.offset(1 as isize) = 0; + *mid_only_flag = 1; + } else if (*state).width_prev_Q14 as i32 != 0 + && (8 * total_rate_bps < 11 * min_mid_rate_bps + || ((frac_Q16 as i64 * (*state).smth_width_Q14 as i64 >> 16) as i32) + < (0.02f64 * ((1) << 14) as f64 + 0.5f64) as i32) + { + pred_Q13[0 as usize] = + (*state).smth_width_Q14 as i32 * pred_Q13[0 as usize] as i16 as i32 >> 14; + pred_Q13[1 as usize] = + (*state).smth_width_Q14 as i32 * pred_Q13[1 as usize] as i16 as i32 >> 14; + silk_stereo_quant_pred(pred_Q13.as_mut_ptr(), ix); + width_Q14 = 0; + pred_Q13[0 as usize] = 0; + pred_Q13[1 as usize] = 0; + } else if (*state).smth_width_Q14 as i32 > (0.95f64 * ((1) << 14) as f64 + 0.5f64) as i32 { + silk_stereo_quant_pred(pred_Q13.as_mut_ptr(), ix); + width_Q14 = ((1 * ((1) << 14)) as f64 + 0.5f64) as i32; + } else { + pred_Q13[0 as usize] = + (*state).smth_width_Q14 as i32 * pred_Q13[0 as usize] as i16 as i32 >> 14; + pred_Q13[1 as usize] = + (*state).smth_width_Q14 as i32 * pred_Q13[1 as usize] as i16 as i32 >> 14; + silk_stereo_quant_pred(pred_Q13.as_mut_ptr(), ix); + width_Q14 = (*state).smth_width_Q14 as i32; + } + if *mid_only_flag as i32 == 1 { + (*state).silent_side_len = ((*state).silent_side_len as i32 + + (frame_length - STEREO_INTERP_LEN_MS * fs_kHz)) + as i16; + if ((*state).silent_side_len as i32) < LA_SHAPE_MS * fs_kHz { + *mid_only_flag = 0; + } else { + (*state).silent_side_len = 10000; + } + } else { + (*state).silent_side_len = 0; + } + if *mid_only_flag as i32 == 0 && *mid_side_rates_bps.offset(1 as isize) < 1 { + *mid_side_rates_bps.offset(1 as isize) = 1; + *mid_side_rates_bps.offset(0 as isize) = + silk_max_int(1, total_rate_bps - *mid_side_rates_bps.offset(1 as isize)); + } + pred0_Q13 = -((*state).pred_prev_Q13[0 as usize] as i32); + pred1_Q13 = -((*state).pred_prev_Q13[1 as usize] as i32); + w_Q24 = (((*state).width_prev_Q14 as u32) << 10) as i32; + denom_Q16 = ((1) << 16) / (8 * fs_kHz); + delta0_Q13 = -if 16 == 1 { + ((pred_Q13[0 as usize] - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 1) + + ((pred_Q13[0 as usize] - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + & 1) + } else { + ((pred_Q13[0 as usize] - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 16 - 1) + + 1 + >> 1 + }; + delta1_Q13 = -if 16 == 1 { + ((pred_Q13[1 as usize] - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 1) + + ((pred_Q13[1 as usize] - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + & 1) + } else { + ((pred_Q13[1 as usize] - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 16 - 1) + + 1 + >> 1 + }; + deltaw_Q24 = ((((width_Q14 - (*state).width_prev_Q14 as i32) as i64 * denom_Q16 as i16 as i64 + >> 16) as i32 as u32) + << 10) as i32; + n = 0; + while n < STEREO_INTERP_LEN_MS * fs_kHz { + pred0_Q13 += delta0_Q13; + pred1_Q13 += delta1_Q13; + w_Q24 += deltaw_Q24; + sum = (((*mid.offset(n as isize) as i32 + + *mid.offset((n + 2) as isize) as i32 + + ((*mid.offset((n + 1) as isize) as u32) << 1) as i32) as u32) + << 9) as i32; + sum = ((w_Q24 as i64 * *side.as_mut_ptr().offset((n + 1) as isize) as i64 >> 16) as i32 + as i64 + + (sum as i64 * pred0_Q13 as i16 as i64 >> 16)) as i32; + sum = (sum as i64 + + (((*mid.offset((n + 1) as isize) as i32 as u32) << 11) as i32 as i64 + * pred1_Q13 as i16 as i64 + >> 16)) as i32; + *x2.offset((n - 1) as isize) = (if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) as i16; + n += 1; + } + pred0_Q13 = -pred_Q13[0 as usize]; + pred1_Q13 = -pred_Q13[1 as usize]; + w_Q24 = ((width_Q14 as u32) << 10) as i32; + n = STEREO_INTERP_LEN_MS * fs_kHz; + while n < frame_length { + sum = (((*mid.offset(n as isize) as i32 + + *mid.offset((n + 2) as isize) as i32 + + ((*mid.offset((n + 1) as isize) as u32) << 1) as i32) as u32) + << 9) as i32; + sum = ((w_Q24 as i64 * *side.as_mut_ptr().offset((n + 1) as isize) as i64 >> 16) as i32 + as i64 + + (sum as i64 * pred0_Q13 as i16 as i64 >> 16)) as i32; + sum = (sum as i64 + + (((*mid.offset((n + 1) as isize) as i32 as u32) << 11) as i32 as i64 + * pred1_Q13 as i16 as i64 + >> 16)) as i32; + *x2.offset((n - 1) as isize) = (if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) as i16; + n += 1; + } + (*state).pred_prev_Q13[0 as usize] = pred_Q13[0 as usize] as i16; + (*state).pred_prev_Q13[1 as usize] = pred_Q13[1 as usize] as i16; + (*state).width_prev_Q14 = width_Q14 as i16; +} diff --git a/vendor/unsafe-libopus/src/silk/stereo_MS_to_LR.rs b/vendor/unsafe-libopus/src/silk/stereo_MS_to_LR.rs new file mode 100644 index 00000000..61cb25fe --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/stereo_MS_to_LR.rs @@ -0,0 +1,172 @@ +pub mod typedef_h { + pub const silk_int16_MIN: i32 = i16::MIN as i32; + pub const silk_int16_MAX: i32 = i16::MAX as i32; +} +use crate::silk::define::STEREO_INTERP_LEN_MS; + +pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN}; +use crate::silk::structs::stereo_dec_state; + +use crate::externs::memcpy; +pub unsafe fn silk_stereo_MS_to_LR( + state: *mut stereo_dec_state, + x1: *mut i16, + x2: *mut i16, + pred_Q13: *const i32, + fs_kHz: i32, + frame_length: i32, +) { + let mut n: i32 = 0; + let mut denom_Q16: i32 = 0; + let mut delta0_Q13: i32 = 0; + let mut delta1_Q13: i32 = 0; + let mut sum: i32 = 0; + let mut diff: i32 = 0; + let mut pred0_Q13: i32 = 0; + let mut pred1_Q13: i32 = 0; + memcpy( + x1 as *mut core::ffi::c_void, + ((*state).sMid).as_mut_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + x2 as *mut core::ffi::c_void, + ((*state).sSide).as_mut_ptr() as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*state).sMid).as_mut_ptr() as *mut core::ffi::c_void, + &mut *x1.offset(frame_length as isize) as *mut i16 as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + memcpy( + ((*state).sSide).as_mut_ptr() as *mut core::ffi::c_void, + &mut *x2.offset(frame_length as isize) as *mut i16 as *const core::ffi::c_void, + 2_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + pred0_Q13 = (*state).pred_prev_Q13[0 as usize] as i32; + pred1_Q13 = (*state).pred_prev_Q13[1 as usize] as i32; + denom_Q16 = ((1) << 16) / (8 * fs_kHz); + delta0_Q13 = if 16 == 1 { + ((*pred_Q13.offset(0 as isize) - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 1) + + ((*pred_Q13.offset(0 as isize) - (*state).pred_prev_Q13[0 as usize] as i32) as i16 + as i32 + * denom_Q16 as i16 as i32 + & 1) + } else { + ((*pred_Q13.offset(0 as isize) - (*state).pred_prev_Q13[0 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 16 - 1) + + 1 + >> 1 + }; + delta1_Q13 = if 16 == 1 { + ((*pred_Q13.offset(1 as isize) - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 1) + + ((*pred_Q13.offset(1 as isize) - (*state).pred_prev_Q13[1 as usize] as i32) as i16 + as i32 + * denom_Q16 as i16 as i32 + & 1) + } else { + ((*pred_Q13.offset(1 as isize) - (*state).pred_prev_Q13[1 as usize] as i32) as i16 as i32 + * denom_Q16 as i16 as i32 + >> 16 - 1) + + 1 + >> 1 + }; + n = 0; + while n < STEREO_INTERP_LEN_MS * fs_kHz { + pred0_Q13 += delta0_Q13; + pred1_Q13 += delta1_Q13; + sum = (((*x1.offset(n as isize) as i32 + + *x1.offset((n + 2) as isize) as i32 + + ((*x1.offset((n + 1) as isize) as u32) << 1) as i32) as u32) + << 9) as i32; + sum = (((*x2.offset((n + 1) as isize) as i32 as u32) << 8) as i32 as i64 + + (sum as i64 * pred0_Q13 as i16 as i64 >> 16)) as i32; + sum = (sum as i64 + + (((*x1.offset((n + 1) as isize) as i32 as u32) << 11) as i32 as i64 + * pred1_Q13 as i16 as i64 + >> 16)) as i32; + *x2.offset((n + 1) as isize) = (if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) as i16; + n += 1; + } + pred0_Q13 = *pred_Q13.offset(0 as isize); + pred1_Q13 = *pred_Q13.offset(1 as isize); + n = STEREO_INTERP_LEN_MS * fs_kHz; + while n < frame_length { + sum = (((*x1.offset(n as isize) as i32 + + *x1.offset((n + 2) as isize) as i32 + + ((*x1.offset((n + 1) as isize) as u32) << 1) as i32) as u32) + << 9) as i32; + sum = (((*x2.offset((n + 1) as isize) as i32 as u32) << 8) as i32 as i64 + + (sum as i64 * pred0_Q13 as i16 as i64 >> 16)) as i32; + sum = (sum as i64 + + (((*x1.offset((n + 1) as isize) as i32 as u32) << 11) as i32 as i64 + * pred1_Q13 as i16 as i64 + >> 16)) as i32; + *x2.offset((n + 1) as isize) = (if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) > silk_int16_MAX + { + silk_int16_MAX + } else if (if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) < silk_int16_MIN + { + silk_int16_MIN + } else if 8 == 1 { + (sum >> 1) + (sum & 1) + } else { + (sum >> 8 - 1) + 1 >> 1 + }) as i16; + n += 1; + } + (*state).pred_prev_Q13[0 as usize] = *pred_Q13.offset(0 as isize) as i16; + (*state).pred_prev_Q13[1 as usize] = *pred_Q13.offset(1 as isize) as i16; + n = 0; + while n < frame_length { + sum = *x1.offset((n + 1) as isize) as i32 + *x2.offset((n + 1) as isize) as i32; + diff = *x1.offset((n + 1) as isize) as i32 - *x2.offset((n + 1) as isize) as i32; + *x1.offset((n + 1) as isize) = (if sum > silk_int16_MAX { + silk_int16_MAX + } else if sum < silk_int16_MIN { + silk_int16_MIN + } else { + sum + }) as i16; + *x2.offset((n + 1) as isize) = (if diff > silk_int16_MAX { + silk_int16_MAX + } else if diff < silk_int16_MIN { + silk_int16_MIN + } else { + diff + }) as i16; + n += 1; + } +} diff --git a/vendor/unsafe-libopus/src/silk/stereo_decode_pred.rs b/vendor/unsafe-libopus/src/silk/stereo_decode_pred.rs new file mode 100644 index 00000000..15b47c58 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/stereo_decode_pred.rs @@ -0,0 +1,38 @@ +use crate::celt::entdec::{ec_dec, ec_dec_icdf}; +use crate::silk::tables_other::{ + silk_stereo_only_code_mid_iCDF, silk_stereo_pred_joint_iCDF, silk_stereo_pred_quant_Q13, + silk_uniform3_iCDF, silk_uniform5_iCDF, +}; + +pub unsafe fn silk_stereo_decode_pred(psRangeDec: &mut ec_dec, pred_Q13: *mut i32) { + let mut n: i32 = 0; + let mut ix: [[i32; 3]; 2] = [[0; 3]; 2]; + let mut low_Q13: i32 = 0; + let mut step_Q13: i32 = 0; + n = ec_dec_icdf(psRangeDec, &silk_stereo_pred_joint_iCDF, 8); + ix[0 as usize][2 as usize] = n / 5; + ix[1 as usize][2 as usize] = n - 5 * ix[0 as usize][2 as usize]; + n = 0; + while n < 2 { + ix[n as usize][0 as usize] = ec_dec_icdf(psRangeDec, &silk_uniform3_iCDF, 8); + ix[n as usize][1 as usize] = ec_dec_icdf(psRangeDec, &silk_uniform5_iCDF, 8); + n += 1; + } + n = 0; + while n < 2 { + ix[n as usize][0 as usize] += 3 * ix[n as usize][2 as usize]; + low_Q13 = silk_stereo_pred_quant_Q13[ix[n as usize][0 as usize] as usize] as i32; + step_Q13 = ((silk_stereo_pred_quant_Q13[(ix[n as usize][0 as usize] + 1) as usize] as i32 + - low_Q13) as i64 + * (0.5f64 / 5 as f64 * ((1) << 16) as f64 + 0.5f64) as i32 as i16 as i64 + >> 16) as i32; + *pred_Q13.offset(n as isize) = + low_Q13 + step_Q13 as i16 as i32 * (2 * ix[n as usize][1 as usize] + 1) as i16 as i32; + n += 1; + } + let ref mut fresh0 = *pred_Q13.offset(0 as isize); + *fresh0 -= *pred_Q13.offset(1 as isize); +} +pub unsafe fn silk_stereo_decode_mid_only(psRangeDec: &mut ec_dec, decode_only_mid: *mut i32) { + *decode_only_mid = ec_dec_icdf(psRangeDec, &silk_stereo_only_code_mid_iCDF, 8); +} diff --git a/vendor/unsafe-libopus/src/silk/stereo_encode_pred.rs b/vendor/unsafe-libopus/src/silk/stereo_encode_pred.rs new file mode 100644 index 00000000..e3460e0e --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/stereo_encode_pred.rs @@ -0,0 +1,39 @@ +use crate::celt::entenc::{ec_enc, ec_enc_icdf}; +use crate::silk::tables_other::{ + silk_stereo_only_code_mid_iCDF, silk_stereo_pred_joint_iCDF, silk_uniform3_iCDF, + silk_uniform5_iCDF, +}; + +pub unsafe fn silk_stereo_encode_pred(psRangeEnc: &mut ec_enc, ix: *mut [i8; 3]) { + let mut n: i32 = 0; + n = 5 * (*ix.offset(0 as isize))[2 as usize] as i32 + + (*ix.offset(1 as isize))[2 as usize] as i32; + assert!(n < 25); + ec_enc_icdf(psRangeEnc, n, &silk_stereo_pred_joint_iCDF, 8); + n = 0; + while n < 2 { + assert!(((*ix.offset(n as isize))[0 as usize] as i32) < 3); + assert!(((*ix.offset(n as isize))[1 as usize] as i32) < 5); + ec_enc_icdf( + psRangeEnc, + (*ix.offset(n as isize))[0 as usize] as i32, + &silk_uniform3_iCDF, + 8, + ); + ec_enc_icdf( + psRangeEnc, + (*ix.offset(n as isize))[1 as usize] as i32, + &silk_uniform5_iCDF, + 8, + ); + n += 1; + } +} +pub unsafe fn silk_stereo_encode_mid_only(psRangeEnc: &mut ec_enc, mid_only_flag: i8) { + ec_enc_icdf( + psRangeEnc, + mid_only_flag as i32, + &silk_stereo_only_code_mid_iCDF, + 8, + ); +} diff --git a/vendor/unsafe-libopus/src/silk/stereo_find_predictor.rs b/vendor/unsafe-libopus/src/silk/stereo_find_predictor.rs new file mode 100644 index 00000000..10375c0f --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/stereo_find_predictor.rs @@ -0,0 +1,90 @@ +use crate::silk::inner_prod_aligned::silk_inner_prod_aligned_scale; +use crate::silk::sum_sqr_shift::silk_sum_sqr_shift; +use crate::silk::SigProc_FIX::silk_max_int; + +use crate::silk::Inlines::{silk_DIV32_varQ, silk_SQRT_APPROX}; + +pub unsafe fn silk_stereo_find_predictor( + ratio_Q14: *mut i32, + x: *const i16, + y: *const i16, + mid_res_amp_Q0: *mut i32, + length: i32, + mut smooth_coef_Q16: i32, +) -> i32 { + let mut scale: i32 = 0; + let mut scale1: i32 = 0; + let mut scale2: i32 = 0; + let mut nrgx: i32 = 0; + let mut nrgy: i32 = 0; + let mut corr: i32 = 0; + let mut pred_Q13: i32 = 0; + let mut pred2_Q10: i32 = 0; + silk_sum_sqr_shift(&mut nrgx, &mut scale1, x, length); + silk_sum_sqr_shift(&mut nrgy, &mut scale2, y, length); + scale = silk_max_int(scale1, scale2); + scale = scale + (scale & 1); + nrgy = nrgy >> scale - scale2; + nrgx = nrgx >> scale - scale1; + nrgx = silk_max_int(nrgx, 1); + corr = silk_inner_prod_aligned_scale(x, y, scale, length); + pred_Q13 = silk_DIV32_varQ(corr, nrgx, 13); + pred_Q13 = if -((1) << 14) > (1) << 14 { + if pred_Q13 > -((1) << 14) { + -((1) << 14) + } else if pred_Q13 < (1) << 14 { + (1) << 14 + } else { + pred_Q13 + } + } else if pred_Q13 > (1) << 14 { + (1) << 14 + } else if pred_Q13 < -((1) << 14) { + -((1) << 14) + } else { + pred_Q13 + }; + pred2_Q10 = (pred_Q13 as i64 * pred_Q13 as i16 as i64 >> 16) as i32; + smooth_coef_Q16 = silk_max_int( + smooth_coef_Q16, + if pred2_Q10 > 0 { pred2_Q10 } else { -pred2_Q10 }, + ); + scale = scale >> 1; + *mid_res_amp_Q0.offset(0 as isize) = (*mid_res_amp_Q0.offset(0 as isize) as i64 + + ((((silk_SQRT_APPROX(nrgx) as u32) << scale) as i32 - *mid_res_amp_Q0.offset(0 as isize)) + as i64 + * smooth_coef_Q16 as i16 as i64 + >> 16)) as i32; + nrgy = nrgy - (((corr as i64 * pred_Q13 as i16 as i64 >> 16) as i32 as u32) << 3 + 1) as i32; + nrgy = nrgy + (((nrgx as i64 * pred2_Q10 as i16 as i64 >> 16) as i32 as u32) << 6) as i32; + *mid_res_amp_Q0.offset(1 as isize) = (*mid_res_amp_Q0.offset(1 as isize) as i64 + + ((((silk_SQRT_APPROX(nrgy) as u32) << scale) as i32 - *mid_res_amp_Q0.offset(1 as isize)) + as i64 + * smooth_coef_Q16 as i16 as i64 + >> 16)) as i32; + *ratio_Q14 = silk_DIV32_varQ( + *mid_res_amp_Q0.offset(1 as isize), + if *mid_res_amp_Q0.offset(0 as isize) > 1 { + *mid_res_amp_Q0.offset(0 as isize) + } else { + 1 + }, + 14, + ); + *ratio_Q14 = if 0 > 32767 { + if *ratio_Q14 > 0 { + 0 + } else if *ratio_Q14 < 32767 { + 32767 + } else { + *ratio_Q14 + } + } else if *ratio_Q14 > 32767 { + 32767 + } else if *ratio_Q14 < 0 { + 0 + } else { + *ratio_Q14 + }; + return pred_Q13; +} diff --git a/vendor/unsafe-libopus/src/silk/stereo_quant_pred.rs b/vendor/unsafe-libopus/src/silk/stereo_quant_pred.rs new file mode 100644 index 00000000..00b8359f --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/stereo_quant_pred.rs @@ -0,0 +1,55 @@ +pub mod typedef_h { + pub const silk_int32_MAX: i32 = i32::MAX; +} +pub use self::typedef_h::silk_int32_MAX; +use crate::silk::define::{STEREO_QUANT_SUB_STEPS, STEREO_QUANT_TAB_SIZE}; +use crate::silk::tables_other::silk_stereo_pred_quant_Q13; + +pub unsafe fn silk_stereo_quant_pred(pred_Q13: *mut i32, ix: *mut [i8; 3]) { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut n: i32 = 0; + let mut low_Q13: i32 = 0; + let mut step_Q13: i32 = 0; + let mut lvl_Q13: i32 = 0; + let mut err_min_Q13: i32 = 0; + let mut err_Q13: i32 = 0; + let mut quant_pred_Q13: i32 = 0; + n = 0; + while n < 2 { + err_min_Q13 = silk_int32_MAX; + i = 0; + 's_18: while i < STEREO_QUANT_TAB_SIZE - 1 { + low_Q13 = silk_stereo_pred_quant_Q13[i as usize] as i32; + step_Q13 = ((silk_stereo_pred_quant_Q13[(i + 1) as usize] as i32 - low_Q13) as i64 + * (0.5f64 / 5 as f64 * ((1) << 16) as f64 + 0.5f64) as i32 as i16 as i64 + >> 16) as i32; + j = 0; + while j < STEREO_QUANT_SUB_STEPS { + lvl_Q13 = low_Q13 + step_Q13 as i16 as i32 * (2 * j + 1) as i16 as i32; + err_Q13 = if *pred_Q13.offset(n as isize) - lvl_Q13 > 0 { + *pred_Q13.offset(n as isize) - lvl_Q13 + } else { + -(*pred_Q13.offset(n as isize) - lvl_Q13) + }; + if !(err_Q13 < err_min_Q13) { + break 's_18; + } + err_min_Q13 = err_Q13; + quant_pred_Q13 = lvl_Q13; + (*ix.offset(n as isize))[0 as usize] = i as i8; + (*ix.offset(n as isize))[1 as usize] = j as i8; + j += 1; + } + i += 1; + } + (*ix.offset(n as isize))[2 as usize] = + ((*ix.offset(n as isize))[0 as usize] as i32 / 3) as i8; + let ref mut fresh0 = (*ix.offset(n as isize))[0 as usize]; + *fresh0 = (*fresh0 as i32 - (*ix.offset(n as isize))[2 as usize] as i32 * 3) as i8; + *pred_Q13.offset(n as isize) = quant_pred_Q13; + n += 1; + } + let ref mut fresh1 = *pred_Q13.offset(0 as isize); + *fresh1 -= *pred_Q13.offset(1 as isize); +} diff --git a/vendor/unsafe-libopus/src/silk/structs.rs b/vendor/unsafe-libopus/src/silk/structs.rs new file mode 100644 index 00000000..d8d54c55 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/structs.rs @@ -0,0 +1,247 @@ +use crate::silk::resampler::ResamplerState; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_NLSF_CB_struct { + pub nVectors: i16, + pub order: i16, + pub quantStepSize_Q16: i16, + pub invQuantStepSize_Q6: i16, + pub CB1_NLSF_Q8: &'static [u8], + pub CB1_Wght_Q9: &'static [i16], + pub CB1_iCDF: &'static [u8], + pub pred_Q8: &'static [u8], + pub ec_sel: &'static [u8], + pub ec_iCDF: &'static [u8], + pub ec_Rates_Q5: &'static [u8], + pub deltaMin_Q15: &'static [i16], +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct SideInfoIndices { + pub GainsIndices: [i8; 4], + pub LTPIndex: [i8; 4], + pub NLSFIndices: [i8; 17], + pub lagIndex: i16, + pub contourIndex: i8, + pub signalType: i8, + pub quantOffsetType: i8, + pub NLSFInterpCoef_Q2: i8, + pub PERIndex: i8, + pub LTP_scaleIndex: i8, + pub Seed: i8, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_PLC_struct { + pub pitchL_Q8: i32, + pub LTPCoef_Q14: [i16; 5], + pub prevLPC_Q12: [i16; 16], + pub last_frame_lost: i32, + pub rand_seed: i32, + pub randScale_Q14: i16, + pub conc_energy: i32, + pub conc_energy_shift: i32, + pub prevLTP_scale_Q14: i16, + pub prevGain_Q16: [i32; 2], + pub fs_kHz: i32, + pub nb_subfr: i32, + pub subfr_length: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_CNG_struct { + pub CNG_exc_buf_Q14: [i32; 320], + pub CNG_smth_NLSF_Q15: [i16; 16], + pub CNG_synth_state: [i32; 16], + pub CNG_smth_Gain_Q16: i32, + pub rand_seed: i32, + pub fs_kHz: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_decoder_state { + pub prev_gain_Q16: i32, + pub exc_Q14: [i32; 320], + pub sLPC_Q14_buf: [i32; 16], + pub outBuf: [i16; 480], + pub lagPrev: i32, + pub LastGainIndex: i8, + pub fs_kHz: i32, + pub fs_API_hz: i32, + pub nb_subfr: i32, + pub frame_length: i32, + pub subfr_length: i32, + pub ltp_mem_length: i32, + pub LPC_order: i32, + pub prevNLSF_Q15: [i16; 16], + pub first_frame_after_reset: i32, + pub pitch_lag_low_bits_iCDF: &'static [u8], + pub pitch_contour_iCDF: &'static [u8], + pub nFramesDecoded: i32, + pub nFramesPerPacket: i32, + pub ec_prevSignalType: i32, + pub ec_prevLagIndex: i16, + pub VAD_flags: [i32; 3], + pub LBRR_flag: i32, + pub LBRR_flags: [i32; 3], + pub resampler_state: ResamplerState, + pub psNLSF_CB: &'static silk_NLSF_CB_struct, + pub indices: SideInfoIndices, + pub sCNG: silk_CNG_struct, + pub lossCnt: i32, + pub prevSignalType: i32, + pub arch: i32, + pub sPLC: silk_PLC_struct, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_decoder_control { + pub pitchL: [i32; 4], + pub Gains_Q16: [i32; 4], + pub PredCoef_Q12: [[i16; 16]; 2], + pub LTPCoef_Q14: [i16; 20], + pub LTP_scale_Q14: i32, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_nsq_state { + pub xq: [i16; 640], + pub sLTP_shp_Q14: [i32; 640], + pub sLPC_Q14: [i32; 96], + pub sAR2_Q14: [i32; 24], + pub sLF_AR_shp_Q14: i32, + pub sDiff_shp_Q14: i32, + pub lagPrev: i32, + pub sLTP_buf_idx: i32, + pub sLTP_shp_buf_idx: i32, + pub rand_seed: i32, + pub prev_gain_Q16: i32, + pub rewhite_flag: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_VAD_state { + pub AnaState: [i32; 2], + pub AnaState1: [i32; 2], + pub AnaState2: [i32; 2], + pub XnrgSubfr: [i32; 4], + pub NrgRatioSmth_Q8: [i32; 4], + pub HPstate: i16, + pub NL: [i32; 4], + pub inv_NL: [i32; 4], + pub NoiseLevelBias: [i32; 4], + pub counter: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_LP_state { + pub In_LP_State: [i32; 2], + pub transition_frame_no: i32, + pub mode: i32, + pub saved_fs_kHz: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct silk_encoder_state { + pub In_HP_State: [i32; 2], + pub variable_HP_smth1_Q15: i32, + pub variable_HP_smth2_Q15: i32, + pub sLP: silk_LP_state, + pub sVAD: silk_VAD_state, + pub sNSQ: silk_nsq_state, + pub prev_NLSFq_Q15: [i16; 16], + pub speech_activity_Q8: i32, + pub allow_bandwidth_switch: i32, + pub LBRRprevLastGainIndex: i8, + pub prevSignalType: i8, + pub prevLag: i32, + pub pitch_LPC_win_length: i32, + pub max_pitch_lag: i32, + pub API_fs_Hz: i32, + pub prev_API_fs_Hz: i32, + pub maxInternal_fs_Hz: i32, + pub minInternal_fs_Hz: i32, + pub desiredInternal_fs_Hz: i32, + pub fs_kHz: i32, + pub nb_subfr: i32, + pub frame_length: i32, + pub subfr_length: i32, + pub ltp_mem_length: i32, + pub la_pitch: i32, + pub la_shape: i32, + pub shapeWinLength: i32, + pub TargetRate_bps: i32, + pub PacketSize_ms: i32, + pub PacketLoss_perc: i32, + pub frameCounter: i32, + pub Complexity: i32, + pub nStatesDelayedDecision: i32, + pub useInterpolatedNLSFs: i32, + pub shapingLPCOrder: i32, + pub predictLPCOrder: i32, + pub pitchEstimationComplexity: i32, + pub pitchEstimationLPCOrder: i32, + pub pitchEstimationThreshold_Q16: i32, + pub sum_log_gain_Q7: i32, + pub NLSF_MSVQ_Survivors: i32, + pub first_frame_after_reset: i32, + pub controlled_since_last_payload: i32, + pub warping_Q16: i32, + pub useCBR: i32, + pub prefillFlag: i32, + pub pitch_lag_low_bits_iCDF: &'static [u8], + pub pitch_contour_iCDF: &'static [u8], + pub psNLSF_CB: &'static silk_NLSF_CB_struct, + pub input_quality_bands_Q15: [i32; 4], + pub input_tilt_Q15: i32, + pub SNR_dB_Q7: i32, + pub VAD_flags: [i8; 3], + pub LBRR_flag: i8, + pub LBRR_flags: [i32; 3], + pub indices: SideInfoIndices, + pub pulses: [i8; 320], + pub arch: i32, + pub inputBuf: [i16; 322], + pub inputBufIx: i32, + pub nFramesPerPacket: i32, + pub nFramesEncoded: i32, + pub nChannelsAPI: i32, + pub nChannelsInternal: i32, + pub channelNb: i32, + pub frames_since_onset: i32, + pub ec_prevSignalType: i32, + pub ec_prevLagIndex: i16, + pub resampler_state: ResamplerState, + pub useDTX: i32, + pub inDTX: i32, + pub noSpeechCounter: i32, + pub useInBandFEC: i32, + pub LBRR_enabled: i32, + pub LBRR_GainIncreases: i32, + pub indices_LBRR: [SideInfoIndices; 3], + pub pulses_LBRR: [[i8; 320]; 3], +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct stereo_enc_state { + pub pred_prev_Q13: [i16; 2], + pub sMid: [i16; 2], + pub sSide: [i16; 2], + pub mid_side_amp_Q0: [i32; 4], + pub smth_width_Q14: i16, + pub width_prev_Q14: i16, + pub silent_side_len: i16, + pub predIx: [[[i8; 3]; 2]; 3], + pub mid_only_flags: [i8; 3], +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct stereo_dec_state { + pub pred_prev_Q13: [i16; 2], + pub sMid: [i16; 2], + pub sSide: [i16; 2], +} diff --git a/vendor/unsafe-libopus/src/silk/sum_sqr_shift.rs b/vendor/unsafe-libopus/src/silk/sum_sqr_shift.rs new file mode 100644 index 00000000..7a88a876 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/sum_sqr_shift.rs @@ -0,0 +1,41 @@ +use crate::silk::macros::silk_CLZ32; +use crate::silk::SigProc_FIX::silk_max_32; + +pub unsafe fn silk_sum_sqr_shift(energy: *mut i32, shift: *mut i32, x: *const i16, len: i32) { + let mut i: i32 = 0; + let mut shft: i32 = 0; + let mut nrg_tmp: u32 = 0; + let mut nrg: i32 = 0; + shft = 31 - silk_CLZ32(len); + nrg = len; + i = 0; + while i < len - 1 { + nrg_tmp = (*x.offset(i as isize) as i32 * *x.offset(i as isize) as i32) as u32; + nrg_tmp = nrg_tmp.wrapping_add( + (*x.offset((i + 1) as isize) as i32 * *x.offset((i + 1) as isize) as i32) as u32, + ) as i32 as u32; + nrg = (nrg as u32).wrapping_add(nrg_tmp >> shft) as i32; + i += 2; + } + if i < len { + nrg_tmp = (*x.offset(i as isize) as i32 * *x.offset(i as isize) as i32) as u32; + nrg = (nrg as u32).wrapping_add(nrg_tmp >> shft) as i32; + } + shft = silk_max_32(0, shft + 3 - silk_CLZ32(nrg)); + nrg = 0; + i = 0; + while i < len - 1 { + nrg_tmp = (*x.offset(i as isize) as i32 * *x.offset(i as isize) as i32) as u32; + nrg_tmp = nrg_tmp.wrapping_add( + (*x.offset((i + 1) as isize) as i32 * *x.offset((i + 1) as isize) as i32) as u32, + ) as i32 as u32; + nrg = (nrg as u32).wrapping_add(nrg_tmp >> shft) as i32; + i += 2; + } + if i < len { + nrg_tmp = (*x.offset(i as isize) as i32 * *x.offset(i as isize) as i32) as u32; + nrg = (nrg as u32).wrapping_add(nrg_tmp >> shft) as i32; + } + *shift = shft; + *energy = nrg; +} diff --git a/vendor/unsafe-libopus/src/silk/table_LSF_cos.rs b/vendor/unsafe-libopus/src/silk/table_LSF_cos.rs new file mode 100644 index 00000000..7dab8e9b --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/table_LSF_cos.rs @@ -0,0 +1,11 @@ +pub static silk_LSFCosTab_FIX_Q12: [i16; 129] = [ + 8192, 8190, 8182, 8170, 8152, 8130, 8104, 8072, 8034, 7994, 7946, 7896, 7840, 7778, 7714, 7644, + 7568, 7490, 7406, 7318, 7226, 7128, 7026, 6922, 6812, 6698, 6580, 6458, 6332, 6204, 6070, 5934, + 5792, 5648, 5502, 5352, 5198, 5040, 4880, 4718, 4552, 4382, 4212, 4038, 3862, 3684, 3502, 3320, + 3136, 2948, 2760, 2570, 2378, 2186, 1990, 1794, 1598, 1400, 1202, 1002, 802, 602, 402, 202, 0, + -202, -402, -602, -802, -1002, -1202, -1400, -1598, -1794, -1990, -2186, -2378, -2570, -2760, + -2948, -3136, -3320, -3502, -3684, -3862, -4038, -4212, -4382, -4552, -4718, -4880, -5040, + -5198, -5352, -5502, -5648, -5792, -5934, -6070, -6204, -6332, -6458, -6580, -6698, -6812, + -6922, -7026, -7128, -7226, -7318, -7406, -7490, -7568, -7644, -7714, -7778, -7840, -7896, + -7946, -7994, -8034, -8072, -8104, -8130, -8152, -8170, -8182, -8190, -8192, +]; diff --git a/vendor/unsafe-libopus/src/silk/tables_LTP.rs b/vendor/unsafe-libopus/src/silk/tables_LTP.rs new file mode 100644 index 00000000..2adc496b --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_LTP.rs @@ -0,0 +1,115 @@ +pub static silk_LTP_per_index_iCDF: [u8; 3] = [179, 99, 0]; +static silk_LTP_gain_iCDF_0: [u8; 8] = [71, 56, 43, 30, 21, 12, 6, 0]; +static silk_LTP_gain_iCDF_1: [u8; 16] = [ + 199, 165, 144, 124, 109, 96, 84, 71, 61, 51, 42, 32, 23, 15, 8, 0, +]; +static silk_LTP_gain_iCDF_2: [u8; 32] = [ + 241, 225, 211, 199, 187, 175, 164, 153, 142, 132, 123, 114, 105, 96, 88, 80, 72, 64, 57, 50, + 44, 38, 33, 29, 24, 20, 16, 12, 9, 5, 2, 0, +]; +static silk_LTP_gain_BITS_Q5_0: [u8; 8] = [15, 131, 138, 138, 155, 155, 173, 173]; +static silk_LTP_gain_BITS_Q5_1: [u8; 16] = [ + 69, 93, 115, 118, 131, 138, 141, 138, 150, 150, 155, 150, 155, 160, 166, 160, +]; +static silk_LTP_gain_BITS_Q5_2: [u8; 32] = [ + 131, 128, 134, 141, 141, 141, 145, 145, 145, 150, 155, 155, 155, 155, 160, 160, 160, 160, 166, + 166, 173, 173, 182, 192, 182, 192, 192, 192, 205, 192, 205, 224, +]; +pub static silk_LTP_gain_iCDF_ptrs: [&[u8]; 3] = [ + &silk_LTP_gain_iCDF_0, + &silk_LTP_gain_iCDF_1, + &silk_LTP_gain_iCDF_2, +]; +pub static silk_LTP_gain_BITS_Q5_ptrs: [&[u8]; 3] = [ + &silk_LTP_gain_BITS_Q5_0, + &silk_LTP_gain_BITS_Q5_1, + &silk_LTP_gain_BITS_Q5_2, +]; +static silk_LTP_gain_vq_0: [[i8; 5]; 8] = [ + [4, 6, 24, 7, 5], + [0, 0, 2, 0, 0], + [12, 28, 41, 13, -4], + [-9, 15, 42, 25, 14], + [1, -2, 62, 41, -9], + [-10, 37, 65, -4, 3], + [-6, 4, 66, 7, -8], + [16, 14, 38, -3, 33], +]; +static silk_LTP_gain_vq_1: [[i8; 5]; 16] = [ + [13, 22, 39, 23, 12], + [-1, 36, 64, 27, -6], + [-7, 10, 55, 43, 17], + [1, 1, 8, 1, 1], + [6, -11, 74, 53, -9], + [-12, 55, 76, -12, 8], + [-3, 3, 93, 27, -4], + [26, 39, 59, 3, -8], + [2, 0, 77, 11, 9], + [-8, 22, 44, -6, 7], + [40, 9, 26, 3, 9], + [-7, 20, 101, -7, 4], + [3, -8, 42, 26, 0], + [-15, 33, 68, 2, 23], + [-2, 55, 46, -2, 15], + [3, -1, 21, 16, 41], +]; +static silk_LTP_gain_vq_2: [[i8; 5]; 32] = [ + [-6, 27, 61, 39, 5], + [-11, 42, 88, 4, 1], + [-2, 60, 65, 6, -4], + [-1, -5, 73, 56, 1], + [-9, 19, 94, 29, -9], + [0, 12, 99, 6, 4], + [8, -19, 102, 46, -13], + [3, 2, 13, 3, 2], + [9, -21, 84, 72, -18], + [-11, 46, 104, -22, 8], + [18, 38, 48, 23, 0], + [-16, 70, 83, -21, 11], + [5, -11, 117, 22, -8], + [-6, 23, 117, -12, 3], + [3, -8, 95, 28, 4], + [-10, 15, 77, 60, -15], + [-1, 4, 124, 2, -4], + [3, 38, 84, 24, -25], + [2, 13, 42, 13, 31], + [21, -4, 56, 46, -1], + [-1, 35, 79, -13, 19], + [-7, 65, 88, -9, -14], + [20, 4, 81, 49, -29], + [20, 0, 75, 3, -17], + [5, -9, 44, 92, -8], + [1, -3, 22, 69, 31], + [-6, 95, 41, -12, 5], + [39, 67, 16, -4, 1], + [0, -6, 120, 55, -36], + [-13, 44, 122, 4, -24], + [81, 5, 11, 3, 7], + [2, 0, 9, 10, 88], +]; +pub static mut silk_LTP_vq_ptrs_Q7: [*const i8; 3] = unsafe { + [ + &*(*silk_LTP_gain_vq_0.as_ptr().offset(0)).as_ptr().offset(0) as *const i8 as *mut i8 + as *const i8, + &*(*silk_LTP_gain_vq_1.as_ptr().offset(0)).as_ptr().offset(0) as *const i8 as *mut i8 + as *const i8, + &*(*silk_LTP_gain_vq_2.as_ptr().offset(0)).as_ptr().offset(0) as *const i8 as *mut i8 + as *const i8, + ] +}; +static silk_LTP_gain_vq_0_gain: [u8; 8] = [46, 2, 90, 87, 93, 91, 82, 98]; +static silk_LTP_gain_vq_1_gain: [u8; 16] = [ + 109, 120, 118, 12, 113, 115, 117, 119, 99, 59, 87, 111, 63, 111, 112, 80, +]; +static silk_LTP_gain_vq_2_gain: [u8; 32] = [ + 126, 124, 125, 124, 129, 121, 126, 23, 132, 127, 127, 127, 126, 127, 122, 133, 130, 134, 101, + 118, 119, 145, 126, 86, 124, 120, 123, 119, 170, 173, 107, 109, +]; +pub static mut silk_LTP_vq_gain_ptrs_Q7: [*const u8; 3] = unsafe { + [ + &*silk_LTP_gain_vq_0_gain.as_ptr().offset(0) as *const u8, + &*silk_LTP_gain_vq_1_gain.as_ptr().offset(0) as *const u8, + &*silk_LTP_gain_vq_2_gain.as_ptr().offset(0) as *const u8, + ] +}; +pub static silk_LTP_vq_sizes: [i8; 3] = [8, 16, 32]; diff --git a/vendor/unsafe-libopus/src/silk/tables_NLSF_CB_NB_MB.rs b/vendor/unsafe-libopus/src/silk/tables_NLSF_CB_NB_MB.rs new file mode 100644 index 00000000..c3393a7b --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_NLSF_CB_NB_MB.rs @@ -0,0 +1,87 @@ +use crate::silk::structs::silk_NLSF_CB_struct; + +static silk_NLSF_CB1_NB_MB_Q8: [u8; 320] = [ + 12, 35, 60, 83, 108, 132, 157, 180, 206, 228, 15, 32, 55, 77, 101, 125, 151, 175, 201, 225, 19, + 42, 66, 89, 114, 137, 162, 184, 209, 230, 12, 25, 50, 72, 97, 120, 147, 172, 200, 223, 26, 44, + 69, 90, 114, 135, 159, 180, 205, 225, 13, 22, 53, 80, 106, 130, 156, 180, 205, 228, 15, 25, 44, + 64, 90, 115, 142, 168, 196, 222, 19, 24, 62, 82, 100, 120, 145, 168, 190, 214, 22, 31, 50, 79, + 103, 120, 151, 170, 203, 227, 21, 29, 45, 65, 106, 124, 150, 171, 196, 224, 30, 49, 75, 97, + 121, 142, 165, 186, 209, 229, 19, 25, 52, 70, 93, 116, 143, 166, 192, 219, 26, 34, 62, 75, 97, + 118, 145, 167, 194, 217, 25, 33, 56, 70, 91, 113, 143, 165, 196, 223, 21, 34, 51, 72, 97, 117, + 145, 171, 196, 222, 20, 29, 50, 67, 90, 117, 144, 168, 197, 221, 22, 31, 48, 66, 95, 117, 146, + 168, 196, 222, 24, 33, 51, 77, 116, 134, 158, 180, 200, 224, 21, 28, 70, 87, 106, 124, 149, + 170, 194, 217, 26, 33, 53, 64, 83, 117, 152, 173, 204, 225, 27, 34, 65, 95, 108, 129, 155, 174, + 210, 225, 20, 26, 72, 99, 113, 131, 154, 176, 200, 219, 34, 43, 61, 78, 93, 114, 155, 177, 205, + 229, 23, 29, 54, 97, 124, 138, 163, 179, 209, 229, 30, 38, 56, 89, 118, 129, 158, 178, 200, + 231, 21, 29, 49, 63, 85, 111, 142, 163, 193, 222, 27, 48, 77, 103, 133, 158, 179, 196, 215, + 232, 29, 47, 74, 99, 124, 151, 176, 198, 220, 237, 33, 42, 61, 76, 93, 121, 155, 174, 207, 225, + 29, 53, 87, 112, 136, 154, 170, 188, 208, 227, 24, 30, 52, 84, 131, 150, 166, 186, 203, 229, + 37, 48, 64, 84, 104, 118, 156, 177, 201, 230, +]; +static silk_NLSF_CB1_Wght_Q9: [i16; 320] = [ + 2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287, 2888, 2580, 2394, 2367, 2314, 2274, + 2274, 2274, 2274, 2194, 2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354, 3216, 2766, + 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194, 2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, + 2407, 2314, 3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261, 3282, 3141, 2580, 2394, + 2247, 2221, 2207, 2194, 2194, 2114, 4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074, + 3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221, 3338, 3488, 2726, 2194, 2261, 2460, + 2354, 2367, 2207, 2101, 2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367, 3779, 3629, + 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048, 3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, + 2274, 2127, 3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101, 2873, 2981, 2633, 2367, + 2407, 2354, 2194, 2247, 2247, 2114, 3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141, + 3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114, 3141, 3272, 2460, 2061, 2287, 2500, + 2367, 2487, 2434, 2181, 3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127, 3423, 3535, + 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274, 3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, + 2474, 2540, 3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261, 3028, 3272, 2740, 2888, + 2740, 2154, 2127, 2287, 2234, 2247, 3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367, + 3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167, 3338, 3366, 2846, 2780, 2327, 2154, + 2274, 2287, 2114, 2061, 2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553, 2407, 2434, + 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700, 3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, + 2354, 2380, 2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367, 3676, 3713, 2234, 1838, + 2181, 2753, 2726, 2673, 2513, 2207, 2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181, +]; +static silk_NLSF_CB1_iCDF_NB_MB: [u8; 64] = [ + 212, 178, 148, 129, 108, 96, 85, 82, 79, 77, 61, 59, 57, 56, 51, 49, 48, 45, 42, 41, 40, 38, + 36, 34, 31, 30, 21, 12, 10, 3, 1, 0, 255, 245, 244, 236, 233, 225, 217, 203, 190, 176, 175, + 161, 149, 136, 125, 114, 102, 91, 81, 71, 60, 52, 43, 35, 28, 20, 19, 18, 12, 11, 5, 0, +]; +static silk_NLSF_CB2_SELECT_NB_MB: [u8; 160] = [ + 16, 0, 0, 0, 0, 99, 66, 36, 36, 34, 36, 34, 34, 34, 34, 83, 69, 36, 52, 34, 116, 102, 70, 68, + 68, 176, 102, 68, 68, 34, 65, 85, 68, 84, 36, 116, 141, 152, 139, 170, 132, 187, 184, 216, 137, + 132, 249, 168, 185, 139, 104, 102, 100, 68, 68, 178, 218, 185, 185, 170, 244, 216, 187, 187, + 170, 244, 187, 187, 219, 138, 103, 155, 184, 185, 137, 116, 183, 155, 152, 136, 132, 217, 184, + 184, 170, 164, 217, 171, 155, 139, 244, 169, 184, 185, 170, 164, 216, 223, 218, 138, 214, 143, + 188, 218, 168, 244, 141, 136, 155, 170, 168, 138, 220, 219, 139, 164, 219, 202, 216, 137, 168, + 186, 246, 185, 139, 116, 185, 219, 185, 138, 100, 100, 134, 100, 102, 34, 68, 68, 100, 68, 168, + 203, 221, 218, 168, 167, 154, 136, 104, 70, 164, 246, 171, 137, 139, 137, 155, 218, 219, 139, +]; +static silk_NLSF_CB2_iCDF_NB_MB: [u8; 72] = [ + 255, 254, 253, 238, 14, 3, 2, 1, 0, 255, 254, 252, 218, 35, 3, 2, 1, 0, 255, 254, 250, 208, 59, + 4, 2, 1, 0, 255, 254, 246, 194, 71, 10, 2, 1, 0, 255, 252, 236, 183, 82, 8, 2, 1, 0, 255, 252, + 235, 180, 90, 17, 2, 1, 0, 255, 248, 224, 171, 97, 30, 4, 1, 0, 255, 254, 236, 173, 95, 37, 7, + 1, 0, +]; +static silk_NLSF_CB2_BITS_NB_MB_Q5: [u8; 72] = [ + 255, 255, 255, 131, 6, 145, 255, 255, 255, 255, 255, 236, 93, 15, 96, 255, 255, 255, 255, 255, + 194, 83, 25, 71, 221, 255, 255, 255, 255, 162, 73, 34, 66, 162, 255, 255, 255, 210, 126, 73, + 43, 57, 173, 255, 255, 255, 201, 125, 71, 48, 58, 130, 255, 255, 255, 166, 110, 73, 57, 62, + 104, 210, 255, 255, 251, 123, 65, 55, 68, 100, 171, 255, +]; +static silk_NLSF_PRED_NB_MB_Q8: [u8; 18] = [ + 179, 138, 140, 148, 151, 149, 153, 151, 163, 116, 67, 82, 59, 92, 72, 100, 89, 92, +]; +static silk_NLSF_DELTA_MIN_NB_MB_Q15: [i16; 11] = [250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461]; +pub static silk_NLSF_CB_NB_MB: silk_NLSF_CB_struct = silk_NLSF_CB_struct { + nVectors: 32, + order: 10, + quantStepSize_Q16: (0.18f64 * ((1) << 16) as f64 + 0.5f64) as i32 as i16, + invQuantStepSize_Q6: (1.0f64 / 0.18f64 * ((1) << 6) as f64 + 0.5f64) as i32 as i16, + CB1_NLSF_Q8: &silk_NLSF_CB1_NB_MB_Q8, + CB1_Wght_Q9: &silk_NLSF_CB1_Wght_Q9, + CB1_iCDF: &silk_NLSF_CB1_iCDF_NB_MB, + pred_Q8: &silk_NLSF_PRED_NB_MB_Q8, + ec_sel: &silk_NLSF_CB2_SELECT_NB_MB, + ec_iCDF: &silk_NLSF_CB2_iCDF_NB_MB, + ec_Rates_Q5: &silk_NLSF_CB2_BITS_NB_MB_Q5, + deltaMin_Q15: &silk_NLSF_DELTA_MIN_NB_MB_Q15, +}; diff --git a/vendor/unsafe-libopus/src/silk/tables_NLSF_CB_WB.rs b/vendor/unsafe-libopus/src/silk/tables_NLSF_CB_WB.rs new file mode 100644 index 00000000..a45b769c --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_NLSF_CB_WB.rs @@ -0,0 +1,114 @@ +use crate::silk::structs::silk_NLSF_CB_struct; + +static silk_NLSF_CB1_WB_Q8: [u8; 512] = [ + 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239, 13, 25, 41, 55, 69, + 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236, 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, + 152, 167, 185, 205, 225, 240, 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, + 221, 237, 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240, 10, 15, 32, + 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236, 8, 21, 37, 51, 65, 79, 98, 113, + 126, 138, 155, 168, 179, 192, 209, 218, 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, + 185, 203, 219, 236, 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237, + 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241, 6, 16, 33, 46, 60, + 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225, 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, + 152, 169, 186, 202, 218, 234, 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, + 216, 233, 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237, 14, 17, 45, + 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240, 9, 16, 29, 40, 56, 71, 88, 103, + 119, 137, 154, 171, 189, 205, 222, 237, 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, + 185, 202, 218, 236, 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237, + 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238, 8, 14, 30, 45, 62, + 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239, 17, 30, 49, 62, 79, 92, 107, 119, 132, + 145, 160, 174, 190, 204, 220, 235, 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, + 205, 222, 238, 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236, 13, 17, + 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237, 17, 22, 35, 42, 58, 78, 93, + 110, 125, 139, 155, 170, 188, 206, 224, 240, 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, + 178, 193, 209, 224, 239, 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, + 241, 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231, 19, 31, 49, 65, + 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242, 18, 31, 52, 68, 88, 103, 117, 126, + 138, 149, 163, 177, 192, 207, 223, 239, 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, + 193, 209, 224, 240, 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237, +]; +static silk_NLSF_CB1_WB_Wght_Q9: [i16; 512] = [ + 3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846, + 3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726, + 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925, + 3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753, + 5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888, + 4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726, + 3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991, + 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673, + 5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700, + 3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963, + 4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873, + 3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660, + 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580, + 3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806, + 5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753, + 4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806, + 5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620, + 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753, + 3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846, + 4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846, + 2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740, + 4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793, + 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780, + 4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700, + 4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888, + 4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888, + 5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925, + 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434, + 2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010, + 2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846, + 3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888, + 3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607, +]; +static silk_NLSF_CB1_iCDF_WB: [u8; 64] = [ + 225, 204, 201, 184, 183, 175, 158, 154, 153, 135, 119, 115, 113, 110, 109, 99, 98, 95, 79, 68, + 52, 50, 48, 45, 43, 32, 31, 27, 18, 10, 3, 0, 255, 251, 235, 230, 212, 201, 196, 182, 167, 166, + 163, 151, 138, 124, 110, 104, 90, 78, 76, 70, 69, 57, 45, 34, 24, 21, 11, 6, 5, 4, 3, 0, +]; +static silk_NLSF_CB2_SELECT_WB: [u8; 256] = [ + 0, 0, 0, 0, 0, 0, 0, 1, 100, 102, 102, 68, 68, 36, 34, 96, 164, 107, 158, 185, 180, 185, 139, + 102, 64, 66, 36, 34, 34, 0, 1, 32, 208, 139, 141, 191, 152, 185, 155, 104, 96, 171, 104, 166, + 102, 102, 102, 132, 1, 0, 0, 0, 0, 16, 16, 0, 80, 109, 78, 107, 185, 139, 103, 101, 208, 212, + 141, 139, 173, 153, 123, 103, 36, 0, 0, 0, 0, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 32, 68, 135, 123, + 119, 119, 103, 69, 98, 68, 103, 120, 118, 118, 102, 71, 98, 134, 136, 157, 184, 182, 153, 139, + 134, 208, 168, 248, 75, 189, 143, 121, 107, 32, 49, 34, 34, 34, 0, 17, 2, 210, 235, 139, 123, + 185, 137, 105, 134, 98, 135, 104, 182, 100, 183, 171, 134, 100, 70, 68, 70, 66, 66, 34, 131, + 64, 166, 102, 68, 36, 2, 1, 0, 134, 166, 102, 68, 34, 34, 66, 132, 212, 246, 158, 139, 107, + 107, 87, 102, 100, 219, 125, 122, 137, 118, 103, 132, 114, 135, 137, 105, 171, 106, 50, 34, + 164, 214, 141, 143, 185, 151, 121, 103, 192, 34, 0, 0, 0, 0, 0, 1, 208, 109, 74, 187, 134, 249, + 159, 137, 102, 110, 154, 118, 87, 101, 119, 101, 0, 2, 0, 36, 36, 66, 68, 35, 96, 164, 102, + 100, 36, 0, 2, 33, 167, 138, 174, 102, 100, 84, 2, 2, 100, 107, 120, 119, 36, 197, 24, 0, +]; +static silk_NLSF_CB2_iCDF_WB: [u8; 72] = [ + 255, 254, 253, 244, 12, 3, 2, 1, 0, 255, 254, 252, 224, 38, 3, 2, 1, 0, 255, 254, 251, 209, 57, + 4, 2, 1, 0, 255, 254, 244, 195, 69, 4, 2, 1, 0, 255, 251, 232, 184, 84, 7, 2, 1, 0, 255, 254, + 240, 186, 86, 14, 2, 1, 0, 255, 254, 239, 178, 91, 30, 5, 1, 0, 255, 248, 227, 177, 100, 19, 2, + 1, 0, +]; +static silk_NLSF_CB2_BITS_WB_Q5: [u8; 72] = [ + 255, 255, 255, 156, 4, 154, 255, 255, 255, 255, 255, 227, 102, 15, 92, 255, 255, 255, 255, 255, + 213, 83, 24, 72, 236, 255, 255, 255, 255, 150, 76, 33, 63, 214, 255, 255, 255, 190, 121, 77, + 43, 55, 185, 255, 255, 255, 245, 137, 71, 43, 59, 139, 255, 255, 255, 255, 131, 66, 50, 66, + 107, 194, 255, 255, 166, 116, 76, 55, 53, 125, 255, 255, +]; +static silk_NLSF_PRED_WB_Q8: [u8; 30] = [ + 175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182, 68, 62, 66, 60, 72, + 117, 85, 90, 118, 136, 151, 142, 160, 142, 155, +]; +static silk_NLSF_DELTA_MIN_WB_Q15: [i16; 17] = + [100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347]; +pub static silk_NLSF_CB_WB: silk_NLSF_CB_struct = silk_NLSF_CB_struct { + nVectors: 32, + order: 16, + quantStepSize_Q16: (0.15f64 * ((1) << 16) as f64 + 0.5f64) as i32 as i16, + invQuantStepSize_Q6: (1.0f64 / 0.15f64 * ((1) << 6) as f64 + 0.5f64) as i32 as i16, + CB1_NLSF_Q8: &silk_NLSF_CB1_WB_Q8, + CB1_Wght_Q9: &silk_NLSF_CB1_WB_Wght_Q9, + CB1_iCDF: &silk_NLSF_CB1_iCDF_WB, + pred_Q8: &silk_NLSF_PRED_WB_Q8, + ec_sel: &silk_NLSF_CB2_SELECT_WB, + ec_iCDF: &silk_NLSF_CB2_iCDF_WB, + ec_Rates_Q5: &silk_NLSF_CB2_BITS_WB_Q5, + deltaMin_Q15: &silk_NLSF_DELTA_MIN_WB_Q15, +}; diff --git a/vendor/unsafe-libopus/src/silk/tables_gain.rs b/vendor/unsafe-libopus/src/silk/tables_gain.rs new file mode 100644 index 00000000..b16b1620 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_gain.rs @@ -0,0 +1,9 @@ +pub static silk_gain_iCDF: [[u8; 8]; 3] = [ + [224, 112, 44, 15, 3, 2, 1, 0], + [254, 237, 192, 132, 70, 23, 4, 0], + [255, 252, 226, 155, 61, 11, 2, 0], +]; +pub static silk_delta_gain_iCDF: [u8; 41] = [ + 250, 245, 234, 203, 71, 50, 42, 38, 35, 33, 31, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, + 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, +]; diff --git a/vendor/unsafe-libopus/src/silk/tables_other.rs b/vendor/unsafe-libopus/src/silk/tables_other.rs new file mode 100644 index 00000000..aae880cc --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_other.rs @@ -0,0 +1,45 @@ +use crate::silk::define::{OFFSET_UVH_Q10, OFFSET_UVL_Q10, OFFSET_VH_Q10, OFFSET_VL_Q10}; + +pub static silk_stereo_pred_quant_Q13: [i16; 16] = [ + -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, 820, 2950, 5000, 6500, 7526, 8266, + 10050, 13732, +]; +pub static silk_stereo_pred_joint_iCDF: [u8; 25] = [ + 249, 247, 246, 245, 244, 234, 210, 202, 201, 200, 197, 174, 82, 59, 56, 55, 54, 46, 22, 12, 11, + 10, 9, 7, 0, +]; +pub static silk_stereo_only_code_mid_iCDF: [u8; 2] = [64, 0]; +static silk_LBRR_flags_2_iCDF: [u8; 3] = [203, 150, 0]; +static silk_LBRR_flags_3_iCDF: [u8; 7] = [215, 195, 166, 125, 110, 82, 0]; +pub static silk_LBRR_flags_iCDF_ptr: [&[u8]; 2] = + [&silk_LBRR_flags_2_iCDF, &silk_LBRR_flags_3_iCDF]; +pub static silk_lsb_iCDF: [u8; 2] = [120, 0]; +pub static silk_LTPscale_iCDF: [u8; 3] = [128, 64, 0]; +pub static silk_type_offset_VAD_iCDF: [u8; 4] = [232, 158, 10, 0]; +pub static silk_type_offset_no_VAD_iCDF: [u8; 2] = [230, 0]; +pub static silk_NLSF_interpolation_factor_iCDF: [u8; 5] = [243, 221, 192, 181, 0]; +pub static silk_Quantization_Offsets_Q10: [[i16; 2]; 2] = [ + [OFFSET_UVL_Q10 as i16, OFFSET_UVH_Q10 as i16], + [OFFSET_VL_Q10 as i16, OFFSET_VH_Q10 as i16], +]; +pub static silk_LTPScales_table_Q14: [i16; 3] = [15565, 12288, 8192]; +pub static silk_uniform3_iCDF: [u8; 3] = [171, 85, 0]; +pub static silk_uniform4_iCDF: [u8; 4] = [192, 128, 64, 0]; +pub static silk_uniform5_iCDF: [u8; 5] = [205, 154, 102, 51, 0]; +pub static silk_uniform6_iCDF: [u8; 6] = [213, 171, 128, 85, 43, 0]; +pub static silk_uniform8_iCDF: [u8; 8] = [224, 192, 160, 128, 96, 64, 32, 0]; +pub static silk_NLSF_EXT_iCDF: [u8; 7] = [100, 40, 16, 7, 3, 1, 0]; +pub static silk_Transition_LP_B_Q28: [[i32; 3]; 5] = [ + [250767114, 501534038, 250767114], + [209867381, 419732057, 209867381], + [170987846, 341967853, 170987846], + [131531482, 263046905, 131531482], + [89306658, 178584282, 89306658], +]; +pub static silk_Transition_LP_A_Q28: [[i32; 2]; 5] = [ + [506393414, 239854379], + [411067935, 169683996], + [306733530, 116694253], + [185807084, 77959395], + [35497197, 57401098], +]; diff --git a/vendor/unsafe-libopus/src/silk/tables_pitch_lag.rs b/vendor/unsafe-libopus/src/silk/tables_pitch_lag.rs new file mode 100644 index 00000000..cb4f7466 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_pitch_lag.rs @@ -0,0 +1,15 @@ +pub static silk_pitch_lag_iCDF: [u8; 32] = [ + 253, 250, 244, 233, 212, 182, 150, 131, 120, 110, 98, 85, 72, 60, 49, 40, 32, 25, 19, 15, 13, + 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, +]; +pub static silk_pitch_delta_iCDF: [u8; 21] = [ + 210, 208, 206, 203, 199, 193, 183, 168, 142, 104, 74, 52, 37, 27, 20, 14, 10, 6, 4, 2, 0, +]; +pub static silk_pitch_contour_iCDF: [u8; 34] = [ + 223, 201, 183, 167, 152, 138, 124, 111, 98, 88, 79, 70, 62, 56, 50, 44, 39, 35, 31, 27, 24, 21, + 18, 16, 14, 12, 10, 8, 6, 4, 3, 2, 1, 0, +]; +pub static silk_pitch_contour_NB_iCDF: [u8; 11] = [188, 176, 155, 138, 119, 97, 67, 43, 26, 10, 0]; +pub static silk_pitch_contour_10_ms_iCDF: [u8; 12] = + [165, 119, 80, 61, 47, 35, 27, 20, 14, 9, 4, 0]; +pub static silk_pitch_contour_10_ms_NB_iCDF: [u8; 3] = [113, 63, 0]; diff --git a/vendor/unsafe-libopus/src/silk/tables_pulses_per_block.rs b/vendor/unsafe-libopus/src/silk/tables_pulses_per_block.rs new file mode 100644 index 00000000..e7e1c7e8 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tables_pulses_per_block.rs @@ -0,0 +1,113 @@ +pub static silk_max_pulses_table: [u8; 4] = [8, 10, 12, 16]; +pub static silk_pulses_per_block_iCDF: [[u8; 18]; 10] = [ + [ + 125, 51, 26, 18, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + ], + [ + 198, 105, 45, 22, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + ], + [ + 213, 162, 116, 83, 59, 43, 32, 24, 18, 15, 12, 9, 7, 6, 5, 3, 2, 0, + ], + [ + 239, 187, 116, 59, 28, 16, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + ], + [ + 250, 229, 188, 135, 86, 51, 30, 19, 13, 10, 8, 6, 5, 4, 3, 2, 1, 0, + ], + [ + 249, 235, 213, 185, 156, 128, 103, 83, 66, 53, 42, 33, 26, 21, 17, 13, 10, 0, + ], + [ + 254, 249, 235, 206, 164, 118, 77, 46, 27, 16, 10, 7, 5, 4, 3, 2, 1, 0, + ], + [ + 255, 253, 249, 239, 220, 191, 156, 119, 85, 57, 37, 23, 15, 10, 6, 4, 2, 0, + ], + [ + 255, 253, 251, 246, 237, 223, 203, 179, 152, 124, 98, 75, 55, 40, 29, 21, 15, 0, + ], + [ + 255, 254, 253, 247, 220, 162, 106, 67, 42, 28, 18, 12, 9, 6, 4, 3, 2, 0, + ], +]; +pub static silk_pulses_per_block_BITS_Q5: [[u8; 18]; 9] = [ + [ + 31, 57, 107, 160, 205, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + ], + [ + 69, 47, 67, 111, 166, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + ], + [ + 82, 74, 79, 95, 109, 128, 145, 160, 173, 205, 205, 205, 224, 255, 255, 224, 255, 224, + ], + [ + 125, 74, 59, 69, 97, 141, 182, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + ], + [ + 173, 115, 85, 73, 76, 92, 115, 145, 173, 205, 224, 224, 255, 255, 255, 255, 255, 255, + ], + [ + 166, 134, 113, 102, 101, 102, 107, 118, 125, 138, 145, 155, 166, 182, 192, 192, 205, 150, + ], + [ + 224, 182, 134, 101, 83, 79, 85, 97, 120, 145, 173, 205, 224, 255, 255, 255, 255, 255, + ], + [ + 255, 224, 192, 150, 120, 101, 92, 89, 93, 102, 118, 134, 160, 182, 192, 224, 224, 224, + ], + [ + 255, 224, 224, 182, 155, 134, 118, 109, 104, 102, 106, 111, 118, 131, 145, 160, 173, 131, + ], +]; +pub static silk_rate_levels_iCDF: [[u8; 9]; 2] = [ + [241, 190, 178, 132, 87, 74, 41, 14, 0], + [223, 193, 157, 140, 106, 57, 39, 18, 0], +]; +pub static silk_rate_levels_BITS_Q5: [[u8; 9]; 2] = [ + [131, 74, 141, 79, 80, 138, 95, 104, 134], + [95, 99, 91, 125, 93, 76, 123, 115, 123], +]; +pub static silk_shell_code_table0: [u8; 152] = [ + 128, 0, 214, 42, 0, 235, 128, 21, 0, 244, 184, 72, 11, 0, 248, 214, 128, 42, 7, 0, 248, 225, + 170, 80, 25, 5, 0, 251, 236, 198, 126, 54, 18, 3, 0, 250, 238, 211, 159, 82, 35, 15, 5, 0, 250, + 231, 203, 168, 128, 88, 53, 25, 6, 0, 252, 238, 216, 185, 148, 108, 71, 40, 18, 4, 0, 253, 243, + 225, 199, 166, 128, 90, 57, 31, 13, 3, 0, 254, 246, 233, 212, 183, 147, 109, 73, 44, 23, 10, 2, + 0, 255, 250, 240, 223, 198, 166, 128, 90, 58, 33, 16, 6, 1, 0, 255, 251, 244, 231, 210, 181, + 146, 110, 75, 46, 25, 12, 5, 1, 0, 255, 253, 248, 238, 221, 196, 164, 128, 92, 60, 35, 18, 8, + 3, 1, 0, 255, 253, 249, 242, 229, 208, 180, 146, 110, 76, 48, 27, 14, 7, 3, 1, 0, +]; +pub static silk_shell_code_table1: [u8; 152] = [ + 129, 0, 207, 50, 0, 236, 129, 20, 0, 245, 185, 72, 10, 0, 249, 213, 129, 42, 6, 0, 250, 226, + 169, 87, 27, 4, 0, 251, 233, 194, 130, 62, 20, 4, 0, 250, 236, 207, 160, 99, 47, 17, 3, 0, 255, + 240, 217, 182, 131, 81, 41, 11, 1, 0, 255, 254, 233, 201, 159, 107, 61, 20, 2, 1, 0, 255, 249, + 233, 206, 170, 128, 86, 50, 23, 7, 1, 0, 255, 250, 238, 217, 186, 148, 108, 70, 39, 18, 6, 1, + 0, 255, 252, 243, 226, 200, 166, 128, 90, 56, 30, 13, 4, 1, 0, 255, 252, 245, 231, 209, 180, + 146, 110, 76, 47, 25, 11, 4, 1, 0, 255, 253, 248, 237, 219, 194, 163, 128, 93, 62, 37, 19, 8, + 3, 1, 0, 255, 254, 250, 241, 226, 205, 177, 145, 111, 79, 51, 30, 15, 6, 2, 1, 0, +]; +pub static silk_shell_code_table2: [u8; 152] = [ + 129, 0, 203, 54, 0, 234, 129, 23, 0, 245, 184, 73, 10, 0, 250, 215, 129, 41, 5, 0, 252, 232, + 173, 86, 24, 3, 0, 253, 240, 200, 129, 56, 15, 2, 0, 253, 244, 217, 164, 94, 38, 10, 1, 0, 253, + 245, 226, 189, 132, 71, 27, 7, 1, 0, 253, 246, 231, 203, 159, 105, 56, 23, 6, 1, 0, 255, 248, + 235, 213, 179, 133, 85, 47, 19, 5, 1, 0, 255, 254, 243, 221, 194, 159, 117, 70, 37, 12, 2, 1, + 0, 255, 254, 248, 234, 208, 171, 128, 85, 48, 22, 8, 2, 1, 0, 255, 254, 250, 240, 220, 189, + 149, 107, 67, 36, 16, 6, 2, 1, 0, 255, 254, 251, 243, 227, 201, 166, 128, 90, 55, 29, 13, 5, 2, + 1, 0, 255, 254, 252, 246, 234, 213, 183, 147, 109, 73, 43, 22, 10, 4, 2, 1, 0, +]; +pub static silk_shell_code_table3: [u8; 152] = [ + 130, 0, 200, 58, 0, 231, 130, 26, 0, 244, 184, 76, 12, 0, 249, 214, 130, 43, 6, 0, 252, 232, + 173, 87, 24, 3, 0, 253, 241, 203, 131, 56, 14, 2, 0, 254, 246, 221, 167, 94, 35, 8, 1, 0, 254, + 249, 232, 193, 130, 65, 23, 5, 1, 0, 255, 251, 239, 211, 162, 99, 45, 15, 4, 1, 0, 255, 251, + 243, 223, 186, 131, 74, 33, 11, 3, 1, 0, 255, 252, 245, 230, 202, 158, 105, 57, 24, 8, 2, 1, 0, + 255, 253, 247, 235, 214, 179, 132, 84, 44, 19, 7, 2, 1, 0, 255, 254, 250, 240, 223, 196, 159, + 112, 69, 36, 15, 6, 2, 1, 0, 255, 254, 253, 245, 231, 209, 176, 136, 93, 55, 27, 11, 3, 2, 1, + 0, 255, 254, 253, 252, 239, 221, 194, 158, 117, 76, 42, 18, 4, 3, 2, 1, 0, +]; +pub static silk_shell_code_table_offsets: [u8; 17] = [ + 0, 0, 2, 5, 9, 14, 20, 27, 35, 44, 54, 65, 77, 90, 104, 119, 135, +]; +pub static silk_sign_iCDF: [u8; 42] = [ + 254, 49, 67, 77, 82, 93, 99, 198, 11, 18, 24, 31, 36, 45, 255, 46, 66, 78, 87, 94, 104, 208, + 14, 21, 32, 42, 51, 66, 255, 94, 104, 109, 112, 115, 118, 248, 53, 69, 80, 88, 95, 102, +]; diff --git a/vendor/unsafe-libopus/src/silk/tests/test_unit_LPC_inv_pred_gain.rs b/vendor/unsafe-libopus/src/silk/tests/test_unit_LPC_inv_pred_gain.rs new file mode 100644 index 00000000..5286bb30 --- /dev/null +++ b/vendor/unsafe-libopus/src/silk/tests/test_unit_LPC_inv_pred_gain.rs @@ -0,0 +1,174 @@ +pub mod stddef_h { + pub type size_t = u64; +} +pub mod stdio_h { + use super::FILE_h::FILE; + { + pub static mut stderr: *mut FILE; + pub fn fprintf(_: *mut FILE, _: *const i8, _: ...) -> i32; + pub fn printf(_: *const i8, _: ...) -> i32; + } +} +pub mod stdlib_h { + { + pub fn rand() -> i32; + pub fn srand(__seed: u32); + } +} +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub mod mathcalls_h { + { + pub fn fabs(_: f64) -> f64; + } +} +use self::cpu_support_h::opus_select_arch; +pub use self::stddef_h::size_t; + +use self::stdio_h::{fprintf, printf, stderr}; +use self::stdlib_h::{rand, srand}; + +pub use self::FILE_h::FILE; +use self::SigProc_FIX_h::silk_LPC_inverse_pred_gain_c; +pub unsafe fn check_stability(A_Q12: *mut i16, order: i32) -> i32 { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut sum_a: i32 = 0; + let mut sum_abs_a: i32 = 0; + sum_abs_a = 0; + sum_a = sum_abs_a; + j = 0; + while j < order { + sum_a += *A_Q12.offset(j as isize) as i32; + sum_abs_a += if *A_Q12.offset(j as isize) as i32 > 0 { + *A_Q12.offset(j as isize) as i32 + } else { + -(*A_Q12.offset(j as isize) as i32) + }; + j += 1; + } + if sum_a >= 4096 { + return 0; + } + if sum_abs_a < 4096 { + return 1; + } + let mut y: [f64; 24] = [ + 0 as f64, + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + ]; + y[0 as usize] = 1 as f64; + i = 0; + while i < 10000 { + let mut sum: f64 = 0 as f64; + j = 0; + while j < order { + sum += y[j as usize] * *A_Q12.offset(j as isize) as i32 as f64; + j += 1; + } + j = order - 1; + while j > 0 { + y[j as usize] = y[(j - 1) as usize]; + j -= 1; + } + y[0 as usize] = sum * (1.0f64 / 4096 as f64); + if !(y[0 as usize] < 10000 as f64 + && y[0 as usize] > -(10000) as f64) + { + return 0; + } + if i & 0x7 == 0 { + let mut amp: f64 = 0 as f64; + j = 0; + while j < order { + amp += y[j as usize].abs(); + j += 1; + } + if amp < 0.00001f64 { + return 1; + } + } + i += 1; + } + return 1; +} +unsafe fn main_0() -> i32 { + let _arch: i32 = opus_select_arch(); + let loop_num: i32 = 10000; + let mut count: i32 = 0; + srand(0); + printf( + b"Testing silk_LPC_inverse_pred_gain() optimization ...\n\0" as *const u8 + as *const i8, + ); + count = 0; + while count < loop_num { + let mut i: u32 = 0; + let mut order: i32 = 0; + let mut shift: u32 = 0; + let mut A_Q12: [i16; 24] = [0; 24]; + let mut gain: i32 = 0; + order = 2; + while order <= 24 { + shift = 0; + while shift < 16 { + i = 0; + while i < 24 { + A_Q12[i as usize] = (rand() as i16 as i32 >> shift) as i16; + i = i.wrapping_add(1); + } + gain = silk_LPC_inverse_pred_gain_c(A_Q12.as_mut_ptr(), order); + if gain != 0 && check_stability(A_Q12.as_mut_ptr(), order) == 0 { + fprintf( + stderr(), + b"**Loop %4d failed!**\n\0" as *const u8 as *const i8, + count, + ); + return 1; + } + shift = shift.wrapping_add(1); + } + order += 2; + } + if count % 500 == 0 { + printf( + b"Loop %4d passed\n\0" as *const u8 as *const i8, + count, + ); + } + count += 1; + } + printf( + b"silk_LPC_inverse_pred_gain() optimization passed\n\0" as *const u8 as *const i8, + ); + return 0; +} +pub fn main() { + unsafe { ::std::process::exit(main_0() as i32) } +} diff --git a/vendor/unsafe-libopus/src/src/analysis.rs b/vendor/unsafe-libopus/src/src/analysis.rs new file mode 100644 index 00000000..97fb608a --- /dev/null +++ b/vendor/unsafe-libopus/src/src/analysis.rs @@ -0,0 +1,1596 @@ +use num_traits::Zero; + +pub mod arch_h { + pub type opus_val32 = f32; + pub type opus_val64 = f32; +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct AnalysisInfo { + pub valid: i32, + pub tonality: f32, + pub tonality_slope: f32, + pub noisiness: f32, + pub activity: f32, + pub music_prob: f32, + pub music_prob_min: f32, + pub music_prob_max: f32, + pub bandwidth: i32, + pub activity_probability: f32, + pub max_pitch_ratio: f32, + pub leak_boost: [u8; 19], +} +pub const LEAK_BANDS: i32 = 19; + +pub type downmix_func = + Option ()>; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct TonalityAnalysisState { + pub arch: i32, + pub application: i32, + pub Fs: i32, + pub angle: [f32; 240], + pub d_angle: [f32; 240], + pub d2_angle: [f32; 240], + pub inmem: [opus_val32; 720], + pub mem_fill: i32, + pub prev_band_tonality: [f32; 18], + pub prev_tonality: f32, + pub prev_bandwidth: i32, + pub E: [[f32; 18]; 8], + pub logE: [[f32; 18]; 8], + pub lowE: [f32; 18], + pub highE: [f32; 18], + pub meanE: [f32; 19], + pub mem: [f32; 32], + pub cmean: [f32; 8], + pub std: [f32; 9], + pub Etracker: f32, + pub lowECount: f32, + pub E_count: i32, + pub count: i32, + pub analysis_offset: i32, + pub write_pos: i32, + pub read_pos: i32, + pub read_subframe: i32, + pub hp_ener_accum: f32, + pub initialized: i32, + pub rnn_state: [f32; 32], + pub downmix_state: [opus_val32; 3], + pub info: [AnalysisInfo; 100], +} +pub const ANALYSIS_BUF_SIZE: i32 = 720; +pub const DETECT_SIZE: i32 = 100; +pub const NB_FRAMES: i32 = 8; +pub const NB_TBANDS: i32 = 18; +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub mod math_h { + pub const M_PI: f64 = 3.14159265358979323846f64; +} +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub use self::arch_h::{opus_val32, opus_val64}; +pub use self::cpu_support_h::opus_select_arch; +pub use self::math_h::M_PI; +use crate::celt::float_cast::float2int; +use crate::celt::kiss_fft::{kiss_fft_cpx, opus_fft_c}; +use crate::celt::mathops::{celt_log, celt_log10, celt_sqrt, fast_atan2f}; +use crate::celt::modes::OpusCustomMode; + +use crate::externs::{memcpy, memmove, memset}; +use crate::src::mlp::{compute_dense, compute_gru}; +use crate::src::mlp_data::{layer0, layer1, layer2}; +use crate::src::opus_encoder::is_digital_silence; + +static mut dct_table: [f32; 128] = [ + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.250000f32, + 0.351851f32, + 0.338330f32, + 0.311806f32, + 0.273300f32, + 0.224292f32, + 0.166664f32, + 0.102631f32, + 0.034654f32, + -0.034654f32, + -0.102631f32, + -0.166664f32, + -0.224292f32, + -0.273300f32, + -0.311806f32, + -0.338330f32, + -0.351851f32, + 0.346760f32, + 0.293969f32, + 0.196424f32, + 0.068975f32, + -0.068975f32, + -0.196424f32, + -0.293969f32, + -0.346760f32, + -0.346760f32, + -0.293969f32, + -0.196424f32, + -0.068975f32, + 0.068975f32, + 0.196424f32, + 0.293969f32, + 0.346760f32, + 0.338330f32, + 0.224292f32, + 0.034654f32, + -0.166664f32, + -0.311806f32, + -0.351851f32, + -0.273300f32, + -0.102631f32, + 0.102631f32, + 0.273300f32, + 0.351851f32, + 0.311806f32, + 0.166664f32, + -0.034654f32, + -0.224292f32, + -0.338330f32, + 0.326641f32, + 0.135299f32, + -0.135299f32, + -0.326641f32, + -0.326641f32, + -0.135299f32, + 0.135299f32, + 0.326641f32, + 0.326641f32, + 0.135299f32, + -0.135299f32, + -0.326641f32, + -0.326641f32, + -0.135299f32, + 0.135299f32, + 0.326641f32, + 0.311806f32, + 0.034654f32, + -0.273300f32, + -0.338330f32, + -0.102631f32, + 0.224292f32, + 0.351851f32, + 0.166664f32, + -0.166664f32, + -0.351851f32, + -0.224292f32, + 0.102631f32, + 0.338330f32, + 0.273300f32, + -0.034654f32, + -0.311806f32, + 0.293969f32, + -0.068975f32, + -0.346760f32, + -0.196424f32, + 0.196424f32, + 0.346760f32, + 0.068975f32, + -0.293969f32, + -0.293969f32, + 0.068975f32, + 0.346760f32, + 0.196424f32, + -0.196424f32, + -0.346760f32, + -0.068975f32, + 0.293969f32, + 0.273300f32, + -0.166664f32, + -0.338330f32, + 0.034654f32, + 0.351851f32, + 0.102631f32, + -0.311806f32, + -0.224292f32, + 0.224292f32, + 0.311806f32, + -0.102631f32, + -0.351851f32, + -0.034654f32, + 0.338330f32, + 0.166664f32, + -0.273300f32, +]; +static mut analysis_window: [f32; 240] = [ + 0.000043f32, + 0.000171f32, + 0.000385f32, + 0.000685f32, + 0.001071f32, + 0.001541f32, + 0.002098f32, + 0.002739f32, + 0.003466f32, + 0.004278f32, + 0.005174f32, + 0.006156f32, + 0.007222f32, + 0.008373f32, + 0.009607f32, + 0.010926f32, + 0.012329f32, + 0.013815f32, + 0.015385f32, + 0.017037f32, + 0.018772f32, + 0.020590f32, + 0.022490f32, + 0.024472f32, + 0.026535f32, + 0.028679f32, + 0.030904f32, + 0.033210f32, + 0.035595f32, + 0.038060f32, + 0.040604f32, + 0.043227f32, + 0.045928f32, + 0.048707f32, + 0.051564f32, + 0.054497f32, + 0.057506f32, + 0.060591f32, + 0.063752f32, + 0.066987f32, + 0.070297f32, + 0.073680f32, + 0.077136f32, + 0.080665f32, + 0.084265f32, + 0.087937f32, + 0.091679f32, + 0.095492f32, + 0.099373f32, + 0.103323f32, + 0.107342f32, + 0.111427f32, + 0.115579f32, + 0.119797f32, + 0.124080f32, + 0.128428f32, + 0.132839f32, + 0.137313f32, + 0.141849f32, + 0.146447f32, + 0.151105f32, + 0.155823f32, + 0.160600f32, + 0.165435f32, + 0.170327f32, + 0.175276f32, + 0.180280f32, + 0.185340f32, + 0.190453f32, + 0.195619f32, + 0.200838f32, + 0.206107f32, + 0.211427f32, + 0.216797f32, + 0.222215f32, + 0.227680f32, + 0.233193f32, + 0.238751f32, + 0.244353f32, + 0.250000f32, + 0.255689f32, + 0.261421f32, + 0.267193f32, + 0.273005f32, + 0.278856f32, + 0.284744f32, + 0.290670f32, + 0.296632f32, + 0.302628f32, + 0.308658f32, + 0.314721f32, + 0.320816f32, + 0.326941f32, + 0.333097f32, + 0.339280f32, + 0.345492f32, + 0.351729f32, + 0.357992f32, + 0.364280f32, + 0.370590f32, + 0.376923f32, + 0.383277f32, + 0.389651f32, + 0.396044f32, + 0.402455f32, + 0.408882f32, + 0.415325f32, + 0.421783f32, + 0.428254f32, + 0.434737f32, + 0.441231f32, + 0.447736f32, + 0.454249f32, + 0.460770f32, + 0.467298f32, + 0.473832f32, + 0.480370f32, + 0.486912f32, + 0.493455f32, + 0.500000f32, + 0.506545f32, + 0.513088f32, + 0.519630f32, + 0.526168f32, + 0.532702f32, + 0.539230f32, + 0.545751f32, + 0.552264f32, + 0.558769f32, + 0.565263f32, + 0.571746f32, + 0.578217f32, + 0.584675f32, + 0.591118f32, + 0.597545f32, + 0.603956f32, + 0.610349f32, + 0.616723f32, + 0.623077f32, + 0.629410f32, + 0.635720f32, + 0.642008f32, + 0.648271f32, + 0.654508f32, + 0.660720f32, + 0.666903f32, + 0.673059f32, + 0.679184f32, + 0.685279f32, + 0.691342f32, + 0.697372f32, + 0.703368f32, + 0.709330f32, + 0.715256f32, + 0.721144f32, + 0.726995f32, + 0.732807f32, + 0.738579f32, + 0.744311f32, + 0.750000f32, + 0.755647f32, + 0.761249f32, + 0.766807f32, + 0.772320f32, + 0.777785f32, + 0.783203f32, + 0.788573f32, + 0.793893f32, + 0.799162f32, + 0.804381f32, + 0.809547f32, + 0.814660f32, + 0.819720f32, + 0.824724f32, + 0.829673f32, + 0.834565f32, + 0.839400f32, + 0.844177f32, + 0.848895f32, + 0.853553f32, + 0.858151f32, + 0.862687f32, + 0.867161f32, + 0.871572f32, + 0.875920f32, + 0.880203f32, + 0.884421f32, + 0.888573f32, + 0.892658f32, + 0.896677f32, + 0.900627f32, + 0.904508f32, + 0.908321f32, + 0.912063f32, + 0.915735f32, + 0.919335f32, + 0.922864f32, + 0.926320f32, + 0.929703f32, + 0.933013f32, + 0.936248f32, + 0.939409f32, + 0.942494f32, + 0.945503f32, + 0.948436f32, + 0.951293f32, + 0.954072f32, + 0.956773f32, + 0.959396f32, + 0.961940f32, + 0.964405f32, + 0.966790f32, + 0.969096f32, + 0.971321f32, + 0.973465f32, + 0.975528f32, + 0.977510f32, + 0.979410f32, + 0.981228f32, + 0.982963f32, + 0.984615f32, + 0.986185f32, + 0.987671f32, + 0.989074f32, + 0.990393f32, + 0.991627f32, + 0.992778f32, + 0.993844f32, + 0.994826f32, + 0.995722f32, + 0.996534f32, + 0.997261f32, + 0.997902f32, + 0.998459f32, + 0.998929f32, + 0.999315f32, + 0.999615f32, + 0.999829f32, + 0.999957f32, + 1.000000f32, +]; +static mut tbands: [i32; 19] = [ + 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240, +]; +pub const NB_TONAL_SKIP_BANDS: i32 = 9; +unsafe fn silk_resampler_down2_hp( + S: *mut opus_val32, + out: *mut opus_val32, + in_0: *const opus_val32, + inLen: i32, +) -> opus_val32 { + let mut k: i32 = 0; + let len2: i32 = inLen / 2; + let mut in32: opus_val32 = 0.; + let mut out32: opus_val32 = 0.; + let mut out32_hp: opus_val32 = 0.; + let mut Y: opus_val32 = 0.; + let mut X: opus_val32 = 0.; + let mut hp_ener: opus_val64 = 0 as opus_val64; + k = 0; + while k < len2 { + in32 = *in_0.offset((2 * k) as isize); + Y = in32 - *S.offset(0 as isize); + X = 0.6074371f32 * Y; + out32 = *S.offset(0 as isize) + X; + *S.offset(0 as isize) = in32 + X; + out32_hp = out32; + in32 = *in_0.offset((2 * k + 1) as isize); + Y = in32 - *S.offset(1 as isize); + X = 0.15063f32 * Y; + out32 = out32 + *S.offset(1 as isize); + out32 = out32 + X; + *S.offset(1 as isize) = in32 + X; + Y = -in32 - *S.offset(2 as isize); + X = 0.15063f32 * Y; + out32_hp = out32_hp + *S.offset(2 as isize); + out32_hp = out32_hp + X; + *S.offset(2 as isize) = -in32 + X; + hp_ener += out32_hp * out32_hp; + *out.offset(k as isize) = 0.5f32 * out32; + k += 1; + } + return hp_ener; +} +unsafe fn downmix_and_resample( + downmix: downmix_func, + mut _x: *const core::ffi::c_void, + y: *mut opus_val32, + S: *mut opus_val32, + mut subframe: i32, + mut offset: i32, + c1: i32, + c2: i32, + C: i32, + Fs: i32, +) -> opus_val32 { + let mut scale: opus_val32 = 0.; + let mut j: i32 = 0; + let mut ret: opus_val32 = 0 as opus_val32; + if subframe == 0 { + return 0 as opus_val32; + } + if Fs == 48000 { + subframe *= 2; + offset *= 2; + } else if Fs == 16000 { + subframe = subframe * 2 / 3; + offset = offset * 2 / 3; + } + let vla = subframe as usize; + let mut tmp: Vec = ::std::vec::from_elem(0., vla); + downmix.expect("non-null function pointer")(_x, tmp.as_mut_ptr(), subframe, offset, c1, c2, C); + scale = 1.0f32 / 32768 as f32; + if c2 == -(2) { + scale /= C as f32; + } else if c2 > -1 { + scale /= 2 as f32; + } + j = 0; + while j < subframe { + let ref mut fresh0 = *tmp.as_mut_ptr().offset(j as isize); + *fresh0 *= scale; + j += 1; + } + if Fs == 48000 { + ret = silk_resampler_down2_hp(S, y, tmp.as_mut_ptr(), subframe); + } else if Fs == 24000 { + memcpy( + y as *mut core::ffi::c_void, + tmp.as_mut_ptr() as *const core::ffi::c_void, + (subframe as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * y.offset_from(tmp.as_mut_ptr()) as i64) as u64), + ); + } else if Fs == 16000 { + let vla_0 = (3 * subframe) as usize; + let mut tmp3x: Vec = ::std::vec::from_elem(0., vla_0); + j = 0; + while j < subframe { + *tmp3x.as_mut_ptr().offset((3 * j) as isize) = *tmp.as_mut_ptr().offset(j as isize); + *tmp3x.as_mut_ptr().offset((3 * j + 1) as isize) = *tmp.as_mut_ptr().offset(j as isize); + *tmp3x.as_mut_ptr().offset((3 * j + 2) as isize) = *tmp.as_mut_ptr().offset(j as isize); + j += 1; + } + silk_resampler_down2_hp(S, y, tmp3x.as_mut_ptr(), 3 * subframe); + } + return ret; +} +pub unsafe fn tonality_analysis_init(tonal: *mut TonalityAnalysisState, Fs: i32) { + (*tonal).arch = opus_select_arch(); + (*tonal).Fs = Fs; + tonality_analysis_reset(tonal); +} +pub unsafe fn tonality_analysis_reset(tonal: *mut TonalityAnalysisState) { + let start: *mut i8 = &mut (*tonal).angle as *mut [f32; 240] as *mut i8; + memset( + start as *mut core::ffi::c_void, + 0, + (::core::mem::size_of::() as u64) + .wrapping_sub(start.offset_from(tonal as *mut i8) as i64 as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); +} +pub unsafe fn tonality_get_info( + tonal: *mut TonalityAnalysisState, + info_out: *mut AnalysisInfo, + len: i32, +) { + let mut pos: i32 = 0; + let mut curr_lookahead: i32 = 0; + let mut tonality_max: f32 = 0.; + let mut tonality_avg: f32 = 0.; + let mut tonality_count: i32 = 0; + let mut i: i32 = 0; + let mut pos0: i32 = 0; + let mut prob_avg: f32 = 0.; + let mut prob_count: f32 = 0.; + let mut prob_min: f32 = 0.; + let mut prob_max: f32 = 0.; + let mut vad_prob: f32 = 0.; + let mut mpos: i32 = 0; + let mut vpos: i32 = 0; + let mut bandwidth_span: i32 = 0; + pos = (*tonal).read_pos; + curr_lookahead = (*tonal).write_pos - (*tonal).read_pos; + if curr_lookahead < 0 { + curr_lookahead += DETECT_SIZE; + } + (*tonal).read_subframe += len / ((*tonal).Fs / 400); + while (*tonal).read_subframe >= 8 { + (*tonal).read_subframe -= 8; + (*tonal).read_pos += 1; + } + if (*tonal).read_pos >= DETECT_SIZE { + (*tonal).read_pos -= DETECT_SIZE; + } + if len > (*tonal).Fs / 50 && pos != (*tonal).write_pos { + pos += 1; + if pos == DETECT_SIZE { + pos = 0; + } + } + if pos == (*tonal).write_pos { + pos -= 1; + } + if pos < 0 { + pos = DETECT_SIZE - 1; + } + pos0 = pos; + memcpy( + info_out as *mut core::ffi::c_void, + &mut *((*tonal).info).as_mut_ptr().offset(pos as isize) as *mut AnalysisInfo + as *const core::ffi::c_void, + 1_u64 + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * info_out.offset_from(&mut *((*tonal).info).as_mut_ptr().offset(pos as isize)) + as i64) as u64, + ), + ); + if (*info_out).valid == 0 { + return; + } + tonality_avg = (*info_out).tonality; + tonality_max = tonality_avg; + tonality_count = 1; + bandwidth_span = 6; + i = 0; + while i < 3 { + pos += 1; + if pos == DETECT_SIZE { + pos = 0; + } + if pos == (*tonal).write_pos { + break; + } + tonality_max = if tonality_max > (*tonal).info[pos as usize].tonality { + tonality_max + } else { + (*tonal).info[pos as usize].tonality + }; + tonality_avg += (*tonal).info[pos as usize].tonality; + tonality_count += 1; + (*info_out).bandwidth = if (*info_out).bandwidth > (*tonal).info[pos as usize].bandwidth { + (*info_out).bandwidth + } else { + (*tonal).info[pos as usize].bandwidth + }; + bandwidth_span -= 1; + i += 1; + } + pos = pos0; + i = 0; + while i < bandwidth_span { + pos -= 1; + if pos < 0 { + pos = DETECT_SIZE - 1; + } + if pos == (*tonal).write_pos { + break; + } + (*info_out).bandwidth = if (*info_out).bandwidth > (*tonal).info[pos as usize].bandwidth { + (*info_out).bandwidth + } else { + (*tonal).info[pos as usize].bandwidth + }; + i += 1; + } + (*info_out).tonality = if tonality_avg / tonality_count as f32 > tonality_max - 0.2f32 { + tonality_avg / tonality_count as f32 + } else { + tonality_max - 0.2f32 + }; + vpos = pos0; + mpos = vpos; + if curr_lookahead > 15 { + mpos += 5; + if mpos >= DETECT_SIZE { + mpos -= DETECT_SIZE; + } + vpos += 1; + if vpos >= DETECT_SIZE { + vpos -= DETECT_SIZE; + } + } + prob_min = 1.0f32; + prob_max = 0.0f32; + vad_prob = (*tonal).info[vpos as usize].activity_probability; + prob_count = if 0.1f32 > vad_prob { 0.1f32 } else { vad_prob }; + prob_avg = (if 0.1f32 > vad_prob { 0.1f32 } else { vad_prob }) + * (*tonal).info[mpos as usize].music_prob; + loop { + let mut pos_vad: f32 = 0.; + mpos += 1; + if mpos == DETECT_SIZE { + mpos = 0; + } + if mpos == (*tonal).write_pos { + break; + } + vpos += 1; + if vpos == DETECT_SIZE { + vpos = 0; + } + if vpos == (*tonal).write_pos { + break; + } + pos_vad = (*tonal).info[vpos as usize].activity_probability; + prob_min = if (prob_avg - 10 as f32 * (vad_prob - pos_vad)) / prob_count < prob_min { + (prob_avg - 10 as f32 * (vad_prob - pos_vad)) / prob_count + } else { + prob_min + }; + prob_max = if (prob_avg + 10 as f32 * (vad_prob - pos_vad)) / prob_count > prob_max { + (prob_avg + 10 as f32 * (vad_prob - pos_vad)) / prob_count + } else { + prob_max + }; + prob_count += if 0.1f32 > pos_vad { 0.1f32 } else { pos_vad }; + prob_avg += (if 0.1f32 > pos_vad { 0.1f32 } else { pos_vad }) + * (*tonal).info[mpos as usize].music_prob; + } + (*info_out).music_prob = prob_avg / prob_count; + prob_min = if prob_avg / prob_count < prob_min { + prob_avg / prob_count + } else { + prob_min + }; + prob_max = if prob_avg / prob_count > prob_max { + prob_avg / prob_count + } else { + prob_max + }; + prob_min = if prob_min > 0.0f32 { prob_min } else { 0.0f32 }; + prob_max = if prob_max < 1.0f32 { prob_max } else { 1.0f32 }; + if curr_lookahead < 10 { + let mut pmin: f32 = 0.; + let mut pmax: f32 = 0.; + pmin = prob_min; + pmax = prob_max; + pos = pos0; + i = 0; + while i + < (if ((*tonal).count - 1) < 15 { + (*tonal).count - 1 + } else { + 15 + }) + { + pos -= 1; + if pos < 0 { + pos = DETECT_SIZE - 1; + } + pmin = if pmin < (*tonal).info[pos as usize].music_prob { + pmin + } else { + (*tonal).info[pos as usize].music_prob + }; + pmax = if pmax > (*tonal).info[pos as usize].music_prob { + pmax + } else { + (*tonal).info[pos as usize].music_prob + }; + i += 1; + } + pmin = if 0.0f32 > pmin - 0.1f32 * vad_prob { + 0.0f32 + } else { + pmin - 0.1f32 * vad_prob + }; + pmax = if 1.0f32 < pmax + 0.1f32 * vad_prob { + 1.0f32 + } else { + pmax + 0.1f32 * vad_prob + }; + prob_min += (1.0f32 - 0.1f32 * curr_lookahead as f32) * (pmin - prob_min); + prob_max += (1.0f32 - 0.1f32 * curr_lookahead as f32) * (pmax - prob_max); + } + (*info_out).music_prob_min = prob_min; + (*info_out).music_prob_max = prob_max; +} +static mut std_feature_bias: [f32; 9] = [ + 5.684947f32, + 3.475288f32, + 1.770634f32, + 1.599784f32, + 3.773215f32, + 2.163313f32, + 1.260756f32, + 1.116868f32, + 1.918795f32, +]; +pub const LEAKAGE_OFFSET: f32 = 2.5f32; +pub const LEAKAGE_SLOPE: f32 = 2.0f32; +unsafe fn tonality_analysis( + tonal: *mut TonalityAnalysisState, + celt_mode: *const OpusCustomMode, + x: *const core::ffi::c_void, + mut len: i32, + mut offset: i32, + c1: i32, + c2: i32, + C: i32, + lsb_depth: i32, + downmix: downmix_func, +) { + let mut i: i32 = 0; + let mut b: i32 = 0; + let N: i32 = 480; + let N2: i32 = 240; + let A: *mut f32 = ((*tonal).angle).as_mut_ptr(); + let dA: *mut f32 = ((*tonal).d_angle).as_mut_ptr(); + let d2A: *mut f32 = ((*tonal).d2_angle).as_mut_ptr(); + let mut band_tonality: [f32; 18] = [0.; 18]; + let mut logE: [f32; 18] = [0.; 18]; + let mut BFCC: [f32; 8] = [0.; 8]; + let mut features: [f32; 25] = [0.; 25]; + let mut frame_tonality: f32 = 0.; + let mut max_frame_tonality: f32 = 0.; + let mut frame_noisiness: f32 = 0.; + let pi4: f32 = (M_PI * M_PI * M_PI * M_PI) as f32; + let mut slope: f32 = 0 as f32; + let mut frame_stationarity: f32 = 0.; + let mut relativeE: f32 = 0.; + let mut frame_probs: [f32; 2] = [0.; 2]; + let mut alpha: f32 = 0.; + let mut alphaE: f32 = 0.; + let mut alphaE2: f32 = 0.; + let mut frame_loudness: f32 = 0.; + let mut bandwidth_mask: f32 = 0.; + let mut is_masked: [i32; 19] = [0; 19]; + let mut bandwidth: i32 = 0; + let mut maxE: f32 = 0 as f32; + let mut noise_floor: f32 = 0.; + let mut remaining: i32 = 0; + let mut info: *mut AnalysisInfo = 0 as *mut AnalysisInfo; + let mut hp_ener: f32 = 0.; + let mut tonality2: [f32; 240] = [0.; 240]; + let mut midE: [f32; 8] = [0.; 8]; + let mut spec_variability: f32 = 0 as f32; + let mut band_log2: [f32; 19] = [0.; 19]; + let mut leakage_from: [f32; 19] = [0.; 19]; + let mut leakage_to: [f32; 19] = [0.; 19]; + let mut layer_out: [f32; 32] = [0.; 32]; + let mut below_max_pitch: f32 = 0.; + let mut above_max_pitch: f32 = 0.; + let mut is_silence: i32 = 0; + if (*tonal).initialized == 0 { + (*tonal).mem_fill = 240; + (*tonal).initialized = 1; + } + alpha = 1.0f32 + / (if (10) < 1 + (*tonal).count { + 10 + } else { + 1 + (*tonal).count + }) as f32; + alphaE = 1.0f32 + / (if (25) < 1 + (*tonal).count { + 25 + } else { + 1 + (*tonal).count + }) as f32; + alphaE2 = 1.0f32 + / (if (100) < 1 + (*tonal).count { + 100 + } else { + 1 + (*tonal).count + }) as f32; + if (*tonal).count <= 1 { + alphaE2 = 1 as f32; + } + if (*tonal).Fs == 48000 { + len /= 2; + offset /= 2; + } else if (*tonal).Fs == 16000 { + len = 3 * len / 2; + offset = 3 * offset / 2; + } + let kfft = (*celt_mode).mdct.kfft[0]; + (*tonal).hp_ener_accum += downmix_and_resample( + downmix, + x, + &mut *((*tonal).inmem) + .as_mut_ptr() + .offset((*tonal).mem_fill as isize), + ((*tonal).downmix_state).as_mut_ptr(), + if len < 720 - (*tonal).mem_fill { + len + } else { + 720 - (*tonal).mem_fill + }, + offset, + c1, + c2, + C, + (*tonal).Fs, + ); + if (*tonal).mem_fill + len < ANALYSIS_BUF_SIZE { + (*tonal).mem_fill += len; + return; + } + hp_ener = (*tonal).hp_ener_accum; + let fresh1 = (*tonal).write_pos; + (*tonal).write_pos = (*tonal).write_pos + 1; + info = &mut *((*tonal).info).as_mut_ptr().offset(fresh1 as isize) as *mut AnalysisInfo; + if (*tonal).write_pos >= DETECT_SIZE { + (*tonal).write_pos -= DETECT_SIZE; + } + is_silence = is_digital_silence(((*tonal).inmem).as_mut_ptr(), 720, 1, lsb_depth); + let mut in_0: [kiss_fft_cpx; 480] = [kiss_fft_cpx::zero(); 480]; + let mut out: [kiss_fft_cpx; 480] = [kiss_fft_cpx::zero(); 480]; + let mut tonality: [f32; 240] = [0.; 240]; + let mut noisiness: [f32; 240] = [0.; 240]; + i = 0; + while i < N2 { + let w: f32 = analysis_window[i as usize]; + in_0[i as usize].re = w * (*tonal).inmem[i as usize]; + in_0[i as usize].im = w * (*tonal).inmem[(N2 + i) as usize]; + in_0[(N - i - 1) as usize].re = w * (*tonal).inmem[(N - i - 1) as usize]; + in_0[(N - i - 1) as usize].im = w * (*tonal).inmem[(N + N2 - i - 1) as usize]; + i += 1; + } + memmove( + ((*tonal).inmem).as_mut_ptr() as *mut core::ffi::c_void, + ((*tonal).inmem) + .as_mut_ptr() + .offset(720 as isize) + .offset(-(240 as isize)) as *const core::ffi::c_void, + 240_u64 + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * ((*tonal).inmem).as_mut_ptr().offset_from( + ((*tonal).inmem) + .as_mut_ptr() + .offset(720 as isize) + .offset(-(240 as isize)), + ) as i64) as u64, + ), + ); + remaining = len - (ANALYSIS_BUF_SIZE - (*tonal).mem_fill); + (*tonal).hp_ener_accum = downmix_and_resample( + downmix, + x, + &mut *((*tonal).inmem).as_mut_ptr().offset(240 as isize), + ((*tonal).downmix_state).as_mut_ptr(), + remaining, + offset + ANALYSIS_BUF_SIZE - (*tonal).mem_fill, + c1, + c2, + C, + (*tonal).Fs, + ); + (*tonal).mem_fill = 240 + remaining; + if is_silence != 0 { + let mut prev_pos: i32 = (*tonal).write_pos - 2; + if prev_pos < 0 { + prev_pos += DETECT_SIZE; + } + memcpy( + info as *mut core::ffi::c_void, + &mut *((*tonal).info).as_mut_ptr().offset(prev_pos as isize) as *mut AnalysisInfo + as *const core::ffi::c_void, + 1_u64 + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * info + .offset_from(&mut *((*tonal).info).as_mut_ptr().offset(prev_pos as isize)) + as i64) as u64, + ), + ); + return; + } + opus_fft_c(kfft, &in_0, &mut out); + if out[0].re != out[0].re { + (*info).valid = 0; + return; + } + i = 1; + while i < N2 { + let mut X1r: f32 = 0.; + let mut X2r: f32 = 0.; + let mut X1i: f32 = 0.; + let mut X2i: f32 = 0.; + let mut angle: f32 = 0.; + let mut d_angle: f32 = 0.; + let mut d2_angle: f32 = 0.; + let mut angle2: f32 = 0.; + let mut d_angle2: f32 = 0.; + let mut d2_angle2: f32 = 0.; + let mut mod1: f32 = 0.; + let mut mod2: f32 = 0.; + let mut avg_mod: f32 = 0.; + X1r = out[i as usize].re + out[(N - i) as usize].re; + X1i = out[i as usize].im - out[(N - i) as usize].im; + X2r = out[i as usize].im + out[(N - i) as usize].im; + X2i = out[(N - i) as usize].re - out[i as usize].re; + angle = (0.5f32 as f64 / M_PI) as f32 * fast_atan2f(X1i, X1r); + d_angle = angle - *A.offset(i as isize); + d2_angle = d_angle - *dA.offset(i as isize); + angle2 = (0.5f32 as f64 / M_PI) as f32 * fast_atan2f(X2i, X2r); + d_angle2 = angle2 - angle; + d2_angle2 = d_angle2 - d_angle; + mod1 = d2_angle - float2int(d2_angle) as f32; + noisiness[i as usize] = (mod1).abs(); + mod1 *= mod1; + mod1 *= mod1; + mod2 = d2_angle2 - float2int(d2_angle2) as f32; + noisiness[i as usize] += (mod2).abs(); + mod2 *= mod2; + mod2 *= mod2; + avg_mod = 0.25f32 * (*d2A.offset(i as isize) + mod1 + 2 as f32 * mod2); + tonality[i as usize] = 1.0f32 / (1.0f32 + 40.0f32 * 16.0f32 * pi4 * avg_mod) - 0.015f32; + tonality2[i as usize] = 1.0f32 / (1.0f32 + 40.0f32 * 16.0f32 * pi4 * mod2) - 0.015f32; + *A.offset(i as isize) = angle2; + *dA.offset(i as isize) = d_angle2; + *d2A.offset(i as isize) = mod2; + i += 1; + } + i = 2; + while i < N2 - 1 { + let tt: f32 = if tonality2[i as usize] + < (if tonality2[(i - 1) as usize] > tonality2[(i + 1) as usize] { + tonality2[(i - 1) as usize] + } else { + tonality2[(i + 1) as usize] + }) { + tonality2[i as usize] + } else if tonality2[(i - 1) as usize] > tonality2[(i + 1) as usize] { + tonality2[(i - 1) as usize] + } else { + tonality2[(i + 1) as usize] + }; + tonality[i as usize] = 0.9f32 + * (if tonality[i as usize] > tt - 0.1f32 { + tonality[i as usize] + } else { + tt - 0.1f32 + }); + i += 1; + } + frame_tonality = 0 as f32; + max_frame_tonality = 0 as f32; + (*info).activity = 0 as f32; + frame_noisiness = 0 as f32; + frame_stationarity = 0 as f32; + if (*tonal).count == 0 { + b = 0; + while b < NB_TBANDS { + (*tonal).lowE[b as usize] = 1e10f64 as f32; + (*tonal).highE[b as usize] = -1e10f64 as f32; + b += 1; + } + } + relativeE = 0 as f32; + frame_loudness = 0 as f32; + let mut E: f32 = 0 as f32; + let mut X1r_0: f32 = 0.; + let mut X2r_0: f32 = 0.; + X1r_0 = 2 as f32 * out[0 as usize].re; + X2r_0 = 2 as f32 * out[0 as usize].im; + E = X1r_0 * X1r_0 + X2r_0 * X2r_0; + i = 1; + while i < 4 { + let binE: f32 = out[i as usize].re * out[i as usize].re + + out[(N - i) as usize].re * out[(N - i) as usize].re + + out[i as usize].im * out[i as usize].im + + out[(N - i) as usize].im * out[(N - i) as usize].im; + E += binE; + i += 1; + } + E = E; + band_log2[0 as usize] = 0.5f32 * std::f32::consts::LOG2_E * celt_log(E + 1e-10f32); + b = 0; + while b < NB_TBANDS { + let mut E_0: f32 = 0 as f32; + let mut tE: f32 = 0 as f32; + let mut nE: f32 = 0 as f32; + let mut L1: f32 = 0.; + let mut L2: f32 = 0.; + let mut stationarity: f32 = 0.; + i = tbands[b as usize]; + while i < tbands[(b + 1) as usize] { + let mut binE_0: f32 = out[i as usize].re * out[i as usize].re + + out[(N - i) as usize].re * out[(N - i) as usize].re + + out[i as usize].im * out[i as usize].im + + out[(N - i) as usize].im * out[(N - i) as usize].im; + binE_0 = binE_0; + E_0 += binE_0; + tE += binE_0 + * (if 0 as f32 > tonality[i as usize] { + 0 as f32 + } else { + tonality[i as usize] + }); + nE += binE_0 * 2.0f32 * (0.5f32 - noisiness[i as usize]); + i += 1; + } + if !(E_0 < 1e9f32) || E_0 != E_0 { + (*info).valid = 0; + return; + } + (*tonal).E[(*tonal).E_count as usize][b as usize] = E_0; + frame_noisiness += nE / (1e-15f32 + E_0); + frame_loudness += celt_sqrt(E_0 + 1e-10f32); + logE[b as usize] = celt_log(E_0 + 1e-10f32); + band_log2[(b + 1) as usize] = 0.5f32 * std::f32::consts::LOG2_E * celt_log(E_0 + 1e-10f32); + (*tonal).logE[(*tonal).E_count as usize][b as usize] = logE[b as usize]; + if (*tonal).count == 0 { + (*tonal).lowE[b as usize] = logE[b as usize]; + (*tonal).highE[b as usize] = (*tonal).lowE[b as usize]; + } + if (*tonal).highE[b as usize] as f64 > (*tonal).lowE[b as usize] as f64 + 7.5f64 { + if (*tonal).highE[b as usize] - logE[b as usize] + > logE[b as usize] - (*tonal).lowE[b as usize] + { + (*tonal).highE[b as usize] -= 0.01f32; + } else { + (*tonal).lowE[b as usize] += 0.01f32; + } + } + if logE[b as usize] > (*tonal).highE[b as usize] { + (*tonal).highE[b as usize] = logE[b as usize]; + (*tonal).lowE[b as usize] = + if (*tonal).highE[b as usize] - 15 as f32 > (*tonal).lowE[b as usize] { + (*tonal).highE[b as usize] - 15 as f32 + } else { + (*tonal).lowE[b as usize] + }; + } else if logE[b as usize] < (*tonal).lowE[b as usize] { + (*tonal).lowE[b as usize] = logE[b as usize]; + (*tonal).highE[b as usize] = + if ((*tonal).lowE[b as usize] + 15 as f32) < (*tonal).highE[b as usize] { + (*tonal).lowE[b as usize] + 15 as f32 + } else { + (*tonal).highE[b as usize] + }; + } + relativeE += (logE[b as usize] - (*tonal).lowE[b as usize]) + / (1e-5f32 + ((*tonal).highE[b as usize] - (*tonal).lowE[b as usize])); + L2 = 0 as f32; + L1 = L2; + i = 0; + while i < NB_FRAMES { + L1 += celt_sqrt((*tonal).E[i as usize][b as usize]); + L2 += (*tonal).E[i as usize][b as usize]; + i += 1; + } + // NB: + // because `1e-15` is specified without a suffix in the upstream, + // this addition is performed as f64 and `celt_sqrt` can't be used + stationarity = 0.99f32.min(L1 / (1e-15 + ((NB_FRAMES as f32 * L2) as f64)).sqrt() as f32); + stationarity *= stationarity; + stationarity *= stationarity; + frame_stationarity += stationarity; + band_tonality[b as usize] = + if tE / (1e-15f32 + E_0) > stationarity * (*tonal).prev_band_tonality[b as usize] { + tE / (1e-15f32 + E_0) + } else { + stationarity * (*tonal).prev_band_tonality[b as usize] + }; + frame_tonality += band_tonality[b as usize]; + if b >= NB_TBANDS - NB_TONAL_SKIP_BANDS { + frame_tonality -= band_tonality[(b - NB_TBANDS + NB_TONAL_SKIP_BANDS) as usize]; + } + max_frame_tonality = + if max_frame_tonality > (1.0f32 + 0.03f32 * (b - 18) as f32) * frame_tonality { + max_frame_tonality + } else { + (1.0f32 + 0.03f32 * (b - 18) as f32) * frame_tonality + }; + slope += band_tonality[b as usize] * (b - 8) as f32; + (*tonal).prev_band_tonality[b as usize] = band_tonality[b as usize]; + b += 1; + } + leakage_from[0 as usize] = band_log2[0 as usize]; + leakage_to[0 as usize] = band_log2[0 as usize] - LEAKAGE_OFFSET; + b = 1; + while b < NB_TBANDS + 1 { + let leak_slope: f32 = + LEAKAGE_SLOPE * (tbands[b as usize] - tbands[(b - 1) as usize]) as f32 / 4 as f32; + leakage_from[b as usize] = + if leakage_from[(b - 1) as usize] + leak_slope < band_log2[b as usize] { + leakage_from[(b - 1) as usize] + leak_slope + } else { + band_log2[b as usize] + }; + leakage_to[b as usize] = + if leakage_to[(b - 1) as usize] - leak_slope > band_log2[b as usize] - 2.5f32 { + leakage_to[(b - 1) as usize] - leak_slope + } else { + band_log2[b as usize] - 2.5f32 + }; + b += 1; + } + b = NB_TBANDS - 2; + while b >= 0 { + let leak_slope_0: f32 = + LEAKAGE_SLOPE * (tbands[(b + 1) as usize] - tbands[b as usize]) as f32 / 4 as f32; + leakage_from[b as usize] = + if leakage_from[(b + 1) as usize] + leak_slope_0 < leakage_from[b as usize] { + leakage_from[(b + 1) as usize] + leak_slope_0 + } else { + leakage_from[b as usize] + }; + leakage_to[b as usize] = + if leakage_to[(b + 1) as usize] - leak_slope_0 > leakage_to[b as usize] { + leakage_to[(b + 1) as usize] - leak_slope_0 + } else { + leakage_to[b as usize] + }; + b -= 1; + } + assert!(18 + 1 <= 19); + b = 0; + while b < NB_TBANDS + 1 { + let boost: f32 = + (if 0 as f32 > leakage_to[b as usize] - band_log2[b as usize] { + 0 as f32 + } else { + leakage_to[b as usize] - band_log2[b as usize] + }) + (if 0 as f32 > band_log2[b as usize] - (leakage_from[b as usize] + 2.5f32) { + 0 as f32 + } else { + band_log2[b as usize] - (leakage_from[b as usize] + 2.5f32) + }); + (*info).leak_boost[b as usize] = (if (255) < (0.5 + (64.0 * boost)).floor() as i32 { + 255 + } else { + (0.5 + (64.0 * boost)).floor() as i32 + }) as u8; + b += 1; + } + while b < LEAK_BANDS { + (*info).leak_boost[b as usize] = 0; + b += 1; + } + i = 0; + while i < NB_FRAMES { + let mut j: i32 = 0; + let mut mindist: f32 = 1e15f32; + j = 0; + while j < NB_FRAMES { + let mut k: i32 = 0; + let mut dist: f32 = 0 as f32; + k = 0; + while k < NB_TBANDS { + let mut tmp: f32 = 0.; + tmp = (*tonal).logE[i as usize][k as usize] - (*tonal).logE[j as usize][k as usize]; + dist += tmp * tmp; + k += 1; + } + if j != i { + mindist = if mindist < dist { mindist } else { dist }; + } + j += 1; + } + spec_variability += mindist; + i += 1; + } + spec_variability = celt_sqrt(spec_variability / NB_FRAMES as f32 / NB_TBANDS as f32); + bandwidth_mask = 0 as f32; + bandwidth = 0; + maxE = 0 as f32; + noise_floor = 5.7e-4f32 / ((1) << (if 0 > lsb_depth - 8 { 0 } else { lsb_depth - 8 })) as f32; + noise_floor *= noise_floor; + below_max_pitch = 0 as f32; + above_max_pitch = 0 as f32; + b = 0; + while b < NB_TBANDS { + let mut E_1: f32 = 0 as f32; + let mut Em: f32 = 0.; + let mut band_start: i32 = 0; + let mut band_end: i32 = 0; + band_start = tbands[b as usize]; + band_end = tbands[(b + 1) as usize]; + i = band_start; + while i < band_end { + let binE_1: f32 = out[i as usize].re * out[i as usize].re + + out[(N - i) as usize].re * out[(N - i) as usize].re + + out[i as usize].im * out[i as usize].im + + out[(N - i) as usize].im * out[(N - i) as usize].im; + E_1 += binE_1; + i += 1; + } + E_1 = E_1; + maxE = if maxE > E_1 { maxE } else { E_1 }; + if band_start < 64 { + below_max_pitch += E_1; + } else { + above_max_pitch += E_1; + } + (*tonal).meanE[b as usize] = if (1 as f32 - alphaE2) * (*tonal).meanE[b as usize] > E_1 { + (1 as f32 - alphaE2) * (*tonal).meanE[b as usize] + } else { + E_1 + }; + Em = if E_1 > (*tonal).meanE[b as usize] { + E_1 + } else { + (*tonal).meanE[b as usize] + }; + if E_1 * 1e9f32 > maxE + && (Em > 3 as f32 * noise_floor * (band_end - band_start) as f32 + || E_1 > noise_floor * (band_end - band_start) as f32) + { + bandwidth = b + 1; + } + is_masked[b as usize] = (E_1 + < (if (*tonal).prev_bandwidth >= b + 1 { + 0.01f32 + } else { + 0.05f32 + }) * bandwidth_mask) as i32; + bandwidth_mask = if 0.05f32 * bandwidth_mask > E_1 { + 0.05f32 * bandwidth_mask + } else { + E_1 + }; + b += 1; + } + if (*tonal).Fs == 48000 { + let mut noise_ratio: f32 = 0.; + let mut Em_0: f32 = 0.; + let E_2: f32 = hp_ener * (1.0f32 / (60 * 60) as f32); + noise_ratio = if (*tonal).prev_bandwidth == 20 { + 10.0f32 + } else { + 30.0f32 + }; + above_max_pitch += E_2; + (*tonal).meanE[b as usize] = if (1 as f32 - alphaE2) * (*tonal).meanE[b as usize] > E_2 { + (1 as f32 - alphaE2) * (*tonal).meanE[b as usize] + } else { + E_2 + }; + Em_0 = if E_2 > (*tonal).meanE[b as usize] { + E_2 + } else { + (*tonal).meanE[b as usize] + }; + if Em_0 > 3 as f32 * noise_ratio * noise_floor * 160 as f32 + || E_2 > noise_ratio * noise_floor * 160 as f32 + { + bandwidth = 20; + } + is_masked[b as usize] = (E_2 + < (if (*tonal).prev_bandwidth == 20 { + 0.01f32 + } else { + 0.05f32 + }) * bandwidth_mask) as i32; + } + if above_max_pitch > below_max_pitch { + (*info).max_pitch_ratio = below_max_pitch / above_max_pitch; + } else { + (*info).max_pitch_ratio = 1 as f32; + } + if bandwidth == 20 && is_masked[NB_TBANDS as usize] != 0 { + bandwidth -= 2; + } else if bandwidth > 0 && bandwidth <= NB_TBANDS && is_masked[(bandwidth - 1) as usize] != 0 { + bandwidth -= 1; + } + if (*tonal).count <= 2 { + bandwidth = 20; + } + frame_loudness = 20f32 * celt_log10(frame_loudness); + (*tonal).Etracker = if (*tonal).Etracker - 0.003f32 > frame_loudness { + (*tonal).Etracker - 0.003f32 + } else { + frame_loudness + }; + (*tonal).lowECount *= 1 as f32 - alphaE; + if frame_loudness < (*tonal).Etracker - 30 as f32 { + (*tonal).lowECount += alphaE; + } + i = 0; + while i < 8 { + let mut sum: f32 = 0 as f32; + b = 0; + while b < 16 { + sum += dct_table[(i * 16 + b) as usize] * logE[b as usize]; + b += 1; + } + BFCC[i as usize] = sum; + i += 1; + } + i = 0; + while i < 8 { + let mut sum_0: f32 = 0 as f32; + b = 0; + while b < 16 { + sum_0 += dct_table[(i * 16 + b) as usize] + * 0.5f32 + * ((*tonal).highE[b as usize] + (*tonal).lowE[b as usize]); + b += 1; + } + midE[i as usize] = sum_0; + i += 1; + } + frame_stationarity /= NB_TBANDS as f32; + relativeE /= NB_TBANDS as f32; + if (*tonal).count < 10 { + relativeE = 0.5f32; + } + frame_noisiness /= NB_TBANDS as f32; + (*info).activity = frame_noisiness + (1 as f32 - frame_noisiness) * relativeE; + frame_tonality = max_frame_tonality / (NB_TBANDS - NB_TONAL_SKIP_BANDS) as f32; + frame_tonality = if frame_tonality > (*tonal).prev_tonality * 0.8f32 { + frame_tonality + } else { + (*tonal).prev_tonality * 0.8f32 + }; + (*tonal).prev_tonality = frame_tonality; + slope /= (8 * 8) as f32; + (*info).tonality_slope = slope; + (*tonal).E_count = ((*tonal).E_count + 1) % NB_FRAMES; + (*tonal).count = if ((*tonal).count + 1) < 10000 { + (*tonal).count + 1 + } else { + 10000 + }; + (*info).tonality = frame_tonality; + i = 0; + while i < 4 { + features[i as usize] = -0.12299f32 * (BFCC[i as usize] + (*tonal).mem[(i + 24) as usize]) + + 0.49195f32 * ((*tonal).mem[i as usize] + (*tonal).mem[(i + 16) as usize]) + + 0.69693f32 * (*tonal).mem[(i + 8) as usize] + - 1.4349f32 * (*tonal).cmean[i as usize]; + i += 1; + } + i = 0; + while i < 4 { + (*tonal).cmean[i as usize] = + (1 as f32 - alpha) * (*tonal).cmean[i as usize] + alpha * BFCC[i as usize]; + i += 1; + } + i = 0; + while i < 4 { + features[(4 + i) as usize] = 0.63246f32 + * (BFCC[i as usize] - (*tonal).mem[(i + 24) as usize]) + + 0.31623f32 * ((*tonal).mem[i as usize] - (*tonal).mem[(i + 16) as usize]); + i += 1; + } + i = 0; + while i < 3 { + features[(8 + i) as usize] = 0.53452f32 + * (BFCC[i as usize] + (*tonal).mem[(i + 24) as usize]) + - 0.26726f32 * ((*tonal).mem[i as usize] + (*tonal).mem[(i + 16) as usize]) + - 0.53452f32 * (*tonal).mem[(i + 8) as usize]; + i += 1; + } + if (*tonal).count > 5 { + i = 0; + while i < 9 { + (*tonal).std[i as usize] = (1 as f32 - alpha) * (*tonal).std[i as usize] + + alpha * features[i as usize] * features[i as usize]; + i += 1; + } + } + i = 0; + while i < 4 { + features[i as usize] = BFCC[i as usize] - midE[i as usize]; + i += 1; + } + i = 0; + while i < 8 { + (*tonal).mem[(i + 24) as usize] = (*tonal).mem[(i + 16) as usize]; + (*tonal).mem[(i + 16) as usize] = (*tonal).mem[(i + 8) as usize]; + (*tonal).mem[(i + 8) as usize] = (*tonal).mem[i as usize]; + (*tonal).mem[i as usize] = BFCC[i as usize]; + i += 1; + } + i = 0; + while i < 9 { + features[(11 + i) as usize] = + celt_sqrt((*tonal).std[i as usize]) - std_feature_bias[i as usize]; + i += 1; + } + features[18 as usize] = spec_variability - 0.78f32; + features[20 as usize] = (*info).tonality - 0.154723f32; + features[21 as usize] = (*info).activity - 0.724643f32; + features[22 as usize] = frame_stationarity - 0.743717f32; + features[23 as usize] = (*info).tonality_slope + 0.069216f32; + features[24 as usize] = (*tonal).lowECount - 0.067930f32; + compute_dense(&layer0, layer_out.as_mut_ptr(), features.as_mut_ptr()); + compute_gru( + &layer1, + ((*tonal).rnn_state).as_mut_ptr(), + layer_out.as_mut_ptr(), + ); + compute_dense( + &layer2, + frame_probs.as_mut_ptr(), + ((*tonal).rnn_state).as_mut_ptr(), + ); + (*info).activity_probability = frame_probs[1 as usize]; + (*info).music_prob = frame_probs[0 as usize]; + (*info).bandwidth = bandwidth; + (*tonal).prev_bandwidth = bandwidth; + (*info).noisiness = frame_noisiness; + (*info).valid = 1; + + #[cfg(feature = "ent-dump")] + eprintln!( + "tonality_analysis: \ + tonality=0x{:x} tonality_slope=0x{:x} noisiness=0x{:x} activity=0x{:x} music_prob=0x{:x} \ + music_prob_min=0x{:x} music_prob_max=0x{:x} activity_probability=0x{:x} max_pitch_ratio=0x{:x}", + (*info).tonality.to_bits(), + (*info).tonality_slope.to_bits(), + (*info).noisiness.to_bits(), + (*info).activity.to_bits(), + (*info).music_prob.to_bits(), + (*info).music_prob_min.to_bits(), + (*info).music_prob_max.to_bits(), + (*info).activity_probability.to_bits(), + (*info).max_pitch_ratio.to_bits() + ); +} +pub unsafe fn run_analysis( + analysis: *mut TonalityAnalysisState, + celt_mode: *const OpusCustomMode, + analysis_pcm: *const core::ffi::c_void, + mut analysis_frame_size: i32, + frame_size: i32, + c1: i32, + c2: i32, + C: i32, + Fs: i32, + lsb_depth: i32, + downmix: downmix_func, + analysis_info: *mut AnalysisInfo, +) { + let mut offset: i32 = 0; + let mut pcm_len: i32 = 0; + analysis_frame_size -= analysis_frame_size & 1; + if !analysis_pcm.is_null() { + analysis_frame_size = if ((100 - 5) * Fs / 50) < analysis_frame_size { + (100 - 5) * Fs / 50 + } else { + analysis_frame_size + }; + pcm_len = analysis_frame_size - (*analysis).analysis_offset; + offset = (*analysis).analysis_offset; + while pcm_len > 0 { + tonality_analysis( + analysis, + celt_mode, + analysis_pcm, + if (Fs / 50) < pcm_len { + Fs / 50 + } else { + pcm_len + }, + offset, + c1, + c2, + C, + lsb_depth, + downmix, + ); + offset += Fs / 50; + pcm_len -= Fs / 50; + } + (*analysis).analysis_offset = analysis_frame_size; + (*analysis).analysis_offset -= frame_size; + } + tonality_get_info(analysis, analysis_info, frame_size); +} diff --git a/vendor/unsafe-libopus/src/src/mapping_matrix.rs b/vendor/unsafe-libopus/src/src/mapping_matrix.rs new file mode 100644 index 00000000..df346383 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/mapping_matrix.rs @@ -0,0 +1,1199 @@ +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; +} +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub use self::arch_h::{opus_val16, opus_val32}; +use crate::celt::float_cast::FLOAT2INT16; +use crate::src::opus_private::align; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct MappingMatrix { + pub rows: i32, + pub cols: i32, + pub gain: i32, +} + +pub unsafe fn mapping_matrix_get_size(rows: i32, cols: i32) -> i32 { + let mut size: i32 = 0; + if rows > 255 || cols > 255 { + return 0; + } + size = ((rows * cols) as u64).wrapping_mul(::core::mem::size_of::() as u64) as i32; + if size > 65004 { + return 0; + } + return align(::core::mem::size_of::() as u64 as i32) + align(size); +} +pub unsafe fn mapping_matrix_get_data(matrix: *const MappingMatrix) -> *mut i16 { + return (matrix as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize) + as *mut core::ffi::c_void as *mut i16; +} +pub unsafe fn mapping_matrix_init( + matrix: *mut MappingMatrix, + rows: i32, + cols: i32, + gain: i32, + data: *const i16, + data_size: i32, +) { + let mut i: i32 = 0; + let mut ptr: *mut i16 = 0 as *mut i16; + assert!( + align(data_size) + == align( + ((rows * cols) as u64).wrapping_mul(::core::mem::size_of::() as u64) as i32 + ) + ); + + (*matrix).rows = rows; + (*matrix).cols = cols; + (*matrix).gain = gain; + ptr = mapping_matrix_get_data(matrix); + i = 0; + while i < rows * cols { + *ptr.offset(i as isize) = *data.offset(i as isize); + i += 1; + } +} +pub unsafe fn mapping_matrix_multiply_channel_in_float( + matrix: *const MappingMatrix, + input: *const f32, + input_rows: i32, + output: *mut opus_val16, + output_row: i32, + output_rows: i32, + frame_size: i32, +) { + let mut matrix_data: *mut i16 = 0 as *mut i16; + let mut i: i32 = 0; + let mut col: i32 = 0; + assert!(input_rows <= (*matrix).cols && output_rows <= (*matrix).rows); + matrix_data = mapping_matrix_get_data(matrix); + i = 0; + while i < frame_size { + let mut tmp: f32 = 0 as f32; + col = 0; + while col < input_rows { + tmp += *matrix_data.offset(((*matrix).rows * col + output_row) as isize) as i32 as f32 + * *input.offset((input_rows * i + col) as isize); + col += 1; + } + *output.offset((output_rows * i) as isize) = 1 as f32 / 32768.0f32 * tmp; + i += 1; + } +} +pub unsafe fn mapping_matrix_multiply_channel_out_float( + matrix: *const MappingMatrix, + input: *const opus_val16, + input_row: i32, + input_rows: i32, + output: *mut f32, + output_rows: i32, + frame_size: i32, +) { + let mut matrix_data: *mut i16 = 0 as *mut i16; + let mut i: i32 = 0; + let mut row: i32 = 0; + let mut input_sample: f32 = 0.; + assert!(input_rows <= (*matrix).cols && output_rows <= (*matrix).rows); + matrix_data = mapping_matrix_get_data(matrix); + i = 0; + while i < frame_size { + input_sample = *input.offset((input_rows * i) as isize); + row = 0; + while row < output_rows { + let tmp: f32 = 1 as f32 / 32768.0f32 + * *matrix_data.offset(((*matrix).rows * input_row + row) as isize) as i32 as f32 + * input_sample; + *output.offset((output_rows * i + row) as isize) += tmp; + row += 1; + } + i += 1; + } +} +pub unsafe fn mapping_matrix_multiply_channel_in_short( + matrix: *const MappingMatrix, + input: *const i16, + input_rows: i32, + output: *mut opus_val16, + output_row: i32, + output_rows: i32, + frame_size: i32, +) { + let mut matrix_data: *mut i16 = 0 as *mut i16; + let mut i: i32 = 0; + let mut col: i32 = 0; + assert!(input_rows <= (*matrix).cols && output_rows <= (*matrix).rows); + matrix_data = mapping_matrix_get_data(matrix); + i = 0; + while i < frame_size { + let mut tmp: opus_val32 = 0 as opus_val32; + col = 0; + while col < input_rows { + tmp += (*matrix_data.offset(((*matrix).rows * col + output_row) as isize) as i32 + * *input.offset((input_rows * i + col) as isize) as i32) as f32; + col += 1; + } + *output.offset((output_rows * i) as isize) = 1 as f32 / (32768.0f32 * 32768.0f32) * tmp; + i += 1; + } +} +pub unsafe fn mapping_matrix_multiply_channel_out_short( + matrix: *const MappingMatrix, + input: *const opus_val16, + input_row: i32, + input_rows: i32, + output: *mut i16, + output_rows: i32, + frame_size: i32, +) { + let mut matrix_data: *mut i16 = 0 as *mut i16; + let mut i: i32 = 0; + let mut row: i32 = 0; + let mut input_sample: i32 = 0; + assert!(input_rows <= (*matrix).cols && output_rows <= (*matrix).rows); + matrix_data = mapping_matrix_get_data(matrix); + i = 0; + while i < frame_size { + input_sample = FLOAT2INT16(*input.offset((input_rows * i) as isize)) as i32; + row = 0; + while row < output_rows { + let tmp: i32 = *matrix_data.offset(((*matrix).rows * input_row + row) as isize) as i32 + * input_sample; + let ref mut fresh0 = *output.offset((output_rows * i + row) as isize); + *fresh0 = (*fresh0 as i32 + (tmp + 16384 >> 15)) as i16; + row += 1; + } + i += 1; + } +} +pub static mut mapping_matrix_foa_mixing: MappingMatrix = { + let init = MappingMatrix { + rows: 6, + cols: 6, + gain: 0, + }; + init +}; +pub static mut mapping_matrix_foa_mixing_data: [i16; 36] = [ + 16384, + 0, + -(16384) as i16, + 23170, + 0, + 0, + 16384, + 23170, + 16384, + 0, + 0, + 0, + 16384, + 0, + -(16384) as i16, + -(23170) as i16, + 0, + 0, + 16384, + -(23170) as i16, + 16384, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, +]; +pub static mut mapping_matrix_soa_mixing: MappingMatrix = { + let init = MappingMatrix { + rows: 11, + cols: 11, + gain: 0, + }; + init +}; +pub static mut mapping_matrix_soa_mixing_data: [i16; 121] = [ + 10923, + 7723, + 13377, + -(13377) as i16, + 11585, + 9459, + 7723, + -(16384) as i16, + -(6689) as i16, + 0, + 0, + 10923, + 7723, + 13377, + 13377, + -(11585) as i16, + 9459, + 7723, + 16384, + -(6689) as i16, + 0, + 0, + 10923, + -(15447) as i16, + 13377, + 0, + 0, + -(18919) as i16, + 7723, + 0, + 13377, + 0, + 0, + 10923, + 7723, + -(13377) as i16, + -(13377) as i16, + 11585, + -(9459) as i16, + 7723, + 16384, + -(6689) as i16, + 0, + 0, + 10923, + -(7723) as i16, + 0, + 13377, + -(16384) as i16, + 0, + -(15447) as i16, + 0, + 9459, + 0, + 0, + 10923, + -(7723) as i16, + 0, + -(13377) as i16, + 16384, + 0, + -(15447) as i16, + 0, + 9459, + 0, + 0, + 10923, + 15447, + 0, + 0, + 0, + 0, + -(15447) as i16, + 0, + -(18919) as i16, + 0, + 0, + 10923, + 7723, + -(13377) as i16, + 13377, + -(11585) as i16, + -(9459) as i16, + 7723, + -(16384) as i16, + -(6689) as i16, + 0, + 0, + 10923, + -(15447) as i16, + -(13377) as i16, + 0, + 0, + 18919, + 7723, + 0, + 13377, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, +]; +pub static mut mapping_matrix_toa_mixing: MappingMatrix = { + let init = MappingMatrix { + rows: 18, + cols: 18, + gain: 0, + }; + init +}; +pub static mut mapping_matrix_toa_mixing_data: [i16; 324] = [ + 8208, + 0, + -(881) as i16, + 14369, + 0, + 0, + -(8192) as i16, + -(4163) as i16, + 13218, + 0, + 0, + 0, + 11095, + -(8836) as i16, + -(6218) as i16, + 14833, + 0, + 0, + 8208, + -(10161) as i16, + 881, + 10161, + -(13218) as i16, + -(2944) as i16, + -(8192) as i16, + 2944, + 0, + -(10488) as i16, + -(6218) as i16, + 6248, + -(11095) as i16, + -(6248) as i16, + 0, + -(10488) as i16, + 0, + 0, + 8208, + 10161, + 881, + -(10161) as i16, + -(13218) as i16, + 2944, + -(8192) as i16, + -(2944) as i16, + 0, + 10488, + -(6218) as i16, + -(6248) as i16, + -(11095) as i16, + 6248, + 0, + 10488, + 0, + 0, + 8176, + 5566, + -(11552) as i16, + 5566, + 9681, + -(11205) as i16, + 8192, + -(11205) as i16, + 0, + 4920, + -(15158) as i16, + 9756, + -(3334) as i16, + 9756, + 0, + -(4920) as i16, + 0, + 0, + 8176, + 7871, + 11552, + 0, + 0, + 15846, + 8192, + 0, + -(9681) as i16, + -(6958) as i16, + 0, + 13797, + 3334, + 0, + -(15158) as i16, + 0, + 0, + 0, + 8176, + 0, + 11552, + 7871, + 0, + 0, + 8192, + 15846, + 9681, + 0, + 0, + 0, + 3334, + 13797, + 15158, + 6958, + 0, + 0, + 8176, + 5566, + -(11552) as i16, + -(5566) as i16, + -(9681) as i16, + -(11205) as i16, + 8192, + 11205, + 0, + 4920, + 15158, + 9756, + -(3334) as i16, + -(9756) as i16, + 0, + 4920, + 0, + 0, + 8208, + 14369, + -(881) as i16, + 0, + 0, + -(4163) as i16, + -(8192) as i16, + 0, + -(13218) as i16, + -(14833) as i16, + 0, + -(8836) as i16, + 11095, + 0, + 6218, + 0, + 0, + 0, + 8208, + 10161, + 881, + 10161, + 13218, + 2944, + -(8192) as i16, + 2944, + 0, + 10488, + 6218, + -(6248) as i16, + -(11095) as i16, + -(6248) as i16, + 0, + -(10488) as i16, + 0, + 0, + 8208, + -(14369) as i16, + -(881) as i16, + 0, + 0, + 4163, + -(8192) as i16, + 0, + -(13218) as i16, + 14833, + 0, + 8836, + 11095, + 0, + 6218, + 0, + 0, + 0, + 8208, + 0, + -(881) as i16, + -(14369) as i16, + 0, + 0, + -(8192) as i16, + 4163, + 13218, + 0, + 0, + 0, + 11095, + 8836, + -(6218) as i16, + -(14833) as i16, + 0, + 0, + 8176, + -(5566) as i16, + -(11552) as i16, + 5566, + -(9681) as i16, + 11205, + 8192, + -(11205) as i16, + 0, + -(4920) as i16, + 15158, + -(9756) as i16, + -(3334) as i16, + 9756, + 0, + -(4920) as i16, + 0, + 0, + 8176, + 0, + 11552, + -(7871) as i16, + 0, + 0, + 8192, + -(15846) as i16, + 9681, + 0, + 0, + 0, + 3334, + -(13797) as i16, + 15158, + -(6958) as i16, + 0, + 0, + 8176, + -(7871) as i16, + 11552, + 0, + 0, + -(15846) as i16, + 8192, + 0, + -(9681) as i16, + 6958, + 0, + -(13797) as i16, + 3334, + 0, + -(15158) as i16, + 0, + 0, + 0, + 8176, + -(5566) as i16, + -(11552) as i16, + -(5566) as i16, + 9681, + 11205, + 8192, + 11205, + 0, + -(4920) as i16, + -(15158) as i16, + -(9756) as i16, + -(3334) as i16, + -(9756) as i16, + 0, + 4920, + 0, + 0, + 8208, + -(10161) as i16, + 881, + -(10161) as i16, + 13218, + -(2944) as i16, + -(8192) as i16, + -(2944) as i16, + 0, + -(10488) as i16, + 6218, + 6248, + -(11095) as i16, + 6248, + 0, + 10488, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, +]; +pub static mut mapping_matrix_foa_demixing: MappingMatrix = { + let init = MappingMatrix { + rows: 6, + cols: 6, + gain: 0, + }; + init +}; +pub static mut mapping_matrix_foa_demixing_data: [i16; 36] = [ + 16384, + 16384, + 16384, + 16384, + 0, + 0, + 0, + 23170, + 0, + -(23170) as i16, + 0, + 0, + -(16384) as i16, + 16384, + -(16384) as i16, + 16384, + 0, + 0, + 23170, + 0, + -(23170) as i16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, +]; +pub static mut mapping_matrix_soa_demixing: MappingMatrix = { + let init = MappingMatrix { + rows: 11, + cols: 11, + gain: 3050, + }; + init +}; +pub static mut mapping_matrix_soa_demixing_data: [i16; 121] = [ + 2771, + 2771, + 2771, + 2771, + 2771, + 2771, + 2771, + 2771, + 2771, + 0, + 0, + 10033, + 10033, + -(20066) as i16, + 10033, + 14189, + 14189, + -(28378) as i16, + 10033, + -(20066) as i16, + 0, + 0, + 3393, + 3393, + 3393, + -(3393) as i16, + 0, + 0, + 0, + -(3393) as i16, + -(3393) as i16, + 0, + 0, + -(17378) as i16, + 17378, + 0, + -(17378) as i16, + -(24576) as i16, + 24576, + 0, + 17378, + 0, + 0, + 0, + -(14189) as i16, + 14189, + 0, + -(14189) as i16, + -(28378) as i16, + 28378, + 0, + 14189, + 0, + 0, + 0, + 2399, + 2399, + -(4799) as i16, + -(2399) as i16, + 0, + 0, + 0, + -(2399) as i16, + 4799, + 0, + 0, + 1959, + 1959, + 1959, + 1959, + -(3918) as i16, + -(3918) as i16, + -(3918) as i16, + 1959, + 1959, + 0, + 0, + -(4156) as i16, + 4156, + 0, + 4156, + 0, + 0, + 0, + -(4156) as i16, + 0, + 0, + 0, + 8192, + 8192, + -(16384) as i16, + 8192, + 16384, + 16384, + -(32768) as i16, + 8192, + -(16384) as i16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8312, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 8312, +]; +pub static mut mapping_matrix_toa_demixing: MappingMatrix = { + let init = MappingMatrix { + rows: 18, + cols: 18, + gain: 0, + }; + init +}; +pub static mut mapping_matrix_toa_demixing_data: [i16; 324] = [ + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 8192, + 0, + 0, + 0, + -(9779) as i16, + 9779, + 6263, + 8857, + 0, + 6263, + 13829, + 9779, + -(13829) as i16, + 0, + -(6263) as i16, + 0, + -(8857) as i16, + -(6263) as i16, + -(9779) as i16, + 0, + 0, + -(3413) as i16, + 3413, + 3413, + -(11359) as i16, + 11359, + 11359, + -(11359) as i16, + -(3413) as i16, + 3413, + -(3413) as i16, + -(3413) as i16, + -(11359) as i16, + 11359, + 11359, + -(11359) as i16, + 3413, + 0, + 0, + 13829, + 9779, + -(9779) as i16, + 6263, + 0, + 8857, + -(6263) as i16, + 0, + 9779, + 0, + -(13829) as i16, + 6263, + -(8857) as i16, + 0, + -(6263) as i16, + -(9779) as i16, + 0, + 0, + 0, + -(15617) as i16, + -(15617) as i16, + 6406, + 0, + 0, + -(6406) as i16, + 0, + 15617, + 0, + 0, + -(6406) as i16, + 0, + 0, + 6406, + 15617, + 0, + 0, + 0, + -(5003) as i16, + 5003, + -(10664) as i16, + 15081, + 0, + -(10664) as i16, + -(7075) as i16, + 5003, + 7075, + 0, + 10664, + 0, + -(15081) as i16, + 10664, + -(5003) as i16, + 0, + 0, + -(8176) as i16, + -(8176) as i16, + -(8176) as i16, + 8208, + 8208, + 8208, + 8208, + -(8176) as i16, + -(8176) as i16, + -(8176) as i16, + -(8176) as i16, + 8208, + 8208, + 8208, + 8208, + -(8176) as i16, + 0, + 0, + -(7075) as i16, + 5003, + -(5003) as i16, + -(10664) as i16, + 0, + 15081, + 10664, + 0, + 5003, + 0, + 7075, + -(10664) as i16, + -(15081) as i16, + 0, + 10664, + -(5003) as i16, + 0, + 0, + 15617, + 0, + 0, + 0, + -(6406) as i16, + 6406, + 0, + -(15617) as i16, + 0, + -(15617) as i16, + 15617, + 0, + 6406, + -(6406) as i16, + 0, + 0, + 0, + 0, + 0, + -(11393) as i16, + 11393, + 2993, + -(4233) as i16, + 0, + 2993, + -(16112) as i16, + 11393, + 16112, + 0, + -(2993) as i16, + 0, + 4233, + -(2993) as i16, + -(11393) as i16, + 0, + 0, + 0, + -(9974) as i16, + -(9974) as i16, + -(13617) as i16, + 0, + 0, + 13617, + 0, + 9974, + 0, + 0, + 13617, + 0, + 0, + -(13617) as i16, + 9974, + 0, + 0, + 0, + 5579, + -(5579) as i16, + 10185, + 14403, + 0, + 10185, + -(7890) as i16, + -(5579) as i16, + 7890, + 0, + -(10185) as i16, + 0, + -(14403) as i16, + -(10185) as i16, + 5579, + 0, + 0, + 11826, + -(11826) as i16, + -(11826) as i16, + -(901) as i16, + 901, + 901, + -(901) as i16, + 11826, + -(11826) as i16, + 11826, + 11826, + -(901) as i16, + 901, + 901, + -(901) as i16, + -(11826) as i16, + 0, + 0, + -(7890) as i16, + -(5579) as i16, + 5579, + 10185, + 0, + 14403, + -(10185) as i16, + 0, + -(5579) as i16, + 0, + 7890, + 10185, + -(14403) as i16, + 0, + -(10185) as i16, + 5579, + 0, + 0, + -(9974) as i16, + 0, + 0, + 0, + -(13617) as i16, + 13617, + 0, + 9974, + 0, + 9974, + -(9974) as i16, + 0, + 13617, + -(13617) as i16, + 0, + 0, + 0, + 0, + 16112, + -(11393) as i16, + 11393, + -(2993) as i16, + 0, + 4233, + 2993, + 0, + -(11393) as i16, + 0, + -(16112) as i16, + -(2993) as i16, + -(4233) as i16, + 0, + 2993, + 11393, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32767, +]; diff --git a/vendor/unsafe-libopus/src/src/mlp.rs b/vendor/unsafe-libopus/src/src/mlp.rs new file mode 100644 index 00000000..e49edede --- /dev/null +++ b/vendor/unsafe-libopus/src/src/mlp.rs @@ -0,0 +1,403 @@ +#[derive(Copy, Clone)] +#[repr(C)] +pub struct DenseLayer { + pub bias: *const i8, + pub input_weights: *const i8, + pub nb_inputs: i32, + pub nb_neurons: i32, + pub sigmoid: i32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct GRULayer { + pub bias: *const i8, + pub input_weights: *const i8, + pub recurrent_weights: *const i8, + pub nb_inputs: i32, + pub nb_neurons: i32, +} +pub const WEIGHTS_SCALE: f32 = 1.0f32 / 128 as f32; + +const tansig_table: [f32; 201] = [ + 0.000000f32, + 0.039979f32, + 0.079830f32, + 0.119427f32, + 0.158649f32, + 0.197375f32, + 0.235496f32, + 0.272905f32, + 0.309507f32, + 0.345214f32, + 0.379949f32, + 0.413644f32, + 0.446244f32, + 0.477700f32, + 0.507977f32, + 0.537050f32, + 0.564900f32, + 0.591519f32, + 0.616909f32, + 0.641077f32, + 0.664037f32, + 0.685809f32, + 0.706419f32, + 0.725897f32, + 0.744277f32, + 0.761594f32, + 0.777888f32, + 0.793199f32, + 0.807569f32, + 0.821040f32, + 0.833655f32, + 0.845456f32, + 0.856485f32, + 0.866784f32, + 0.876393f32, + 0.885352f32, + 0.893698f32, + 0.901468f32, + 0.908698f32, + 0.915420f32, + 0.921669f32, + 0.927473f32, + 0.932862f32, + 0.937863f32, + 0.942503f32, + 0.946806f32, + 0.950795f32, + 0.954492f32, + 0.957917f32, + 0.961090f32, + 0.964028f32, + 0.966747f32, + 0.969265f32, + 0.971594f32, + 0.973749f32, + 0.975743f32, + 0.977587f32, + 0.979293f32, + 0.980869f32, + 0.982327f32, + 0.983675f32, + 0.984921f32, + 0.986072f32, + 0.987136f32, + 0.988119f32, + 0.989027f32, + 0.989867f32, + 0.990642f32, + 0.991359f32, + 0.992020f32, + 0.992631f32, + 0.993196f32, + 0.993718f32, + 0.994199f32, + 0.994644f32, + 0.995055f32, + 0.995434f32, + 0.995784f32, + 0.996108f32, + 0.996407f32, + 0.996682f32, + 0.996937f32, + 0.997172f32, + 0.997389f32, + 0.997590f32, + 0.997775f32, + 0.997946f32, + 0.998104f32, + 0.998249f32, + 0.998384f32, + 0.998508f32, + 0.998623f32, + 0.998728f32, + 0.998826f32, + 0.998916f32, + 0.999000f32, + 0.999076f32, + 0.999147f32, + 0.999213f32, + 0.999273f32, + 0.999329f32, + 0.999381f32, + 0.999428f32, + 0.999472f32, + 0.999513f32, + 0.999550f32, + 0.999585f32, + 0.999617f32, + 0.999646f32, + 0.999673f32, + 0.999699f32, + 0.999722f32, + 0.999743f32, + 0.999763f32, + 0.999781f32, + 0.999798f32, + 0.999813f32, + 0.999828f32, + 0.999841f32, + 0.999853f32, + 0.999865f32, + 0.999875f32, + 0.999885f32, + 0.999893f32, + 0.999902f32, + 0.999909f32, + 0.999916f32, + 0.999923f32, + 0.999929f32, + 0.999934f32, + 0.999939f32, + 0.999944f32, + 0.999948f32, + 0.999952f32, + 0.999956f32, + 0.999959f32, + 0.999962f32, + 0.999965f32, + 0.999968f32, + 0.999970f32, + 0.999973f32, + 0.999975f32, + 0.999977f32, + 0.999978f32, + 0.999980f32, + 0.999982f32, + 0.999983f32, + 0.999984f32, + 0.999986f32, + 0.999987f32, + 0.999988f32, + 0.999989f32, + 0.999990f32, + 0.999990f32, + 0.999991f32, + 0.999992f32, + 0.999992f32, + 0.999993f32, + 0.999994f32, + 0.999994f32, + 0.999994f32, + 0.999995f32, + 0.999995f32, + 0.999996f32, + 0.999996f32, + 0.999996f32, + 0.999997f32, + 0.999997f32, + 0.999997f32, + 0.999997f32, + 0.999997f32, + 0.999998f32, + 0.999998f32, + 0.999998f32, + 0.999998f32, + 0.999998f32, + 0.999998f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 0.999999f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, + 1.000000f32, +]; + +#[inline] +unsafe fn tansig_approx(mut x: f32) -> f32 { + let mut i: i32 = 0; + let mut y: f32 = 0.; + let mut dy: f32 = 0.; + let mut sign: f32 = 1 as f32; + if !(x < 8 as f32) { + return 1 as f32; + } + if !(x > -(8) as f32) { + return -1 as f32; + } + if x != x { + return 0 as f32; + } + if x < 0 as f32 { + x = -x; + sign = -1 as f32; + } + i = (0.5f32 + 25.0 * x).floor() as i32; + x -= 0.04f32 * i as f32; + y = tansig_table[i as usize]; + dy = 1 as f32 - y * y; + y = y + x * dy * (1 as f32 - y * x); + return sign * y; +} +#[inline] +unsafe fn sigmoid_approx(x: f32) -> f32 { + return 0.5f32 + 0.5f32 * tansig_approx(0.5f32 * x); +} +unsafe fn gemm_accum( + out: *mut f32, + weights: *const i8, + rows: i32, + cols: i32, + col_stride: i32, + x: *const f32, +) { + let mut i: i32 = 0; + let mut j: i32 = 0; + i = 0; + while i < rows { + j = 0; + while j < cols { + *out.offset(i as isize) += *weights.offset((j * col_stride + i) as isize) as i32 as f32 + * *x.offset(j as isize); + j += 1; + } + i += 1; + } +} +pub unsafe fn compute_dense(layer: *const DenseLayer, output: *mut f32, input: *const f32) { + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut M: i32 = 0; + let mut stride: i32 = 0; + M = (*layer).nb_inputs; + N = (*layer).nb_neurons; + stride = N; + i = 0; + while i < N { + *output.offset(i as isize) = *((*layer).bias).offset(i as isize) as f32; + i += 1; + } + gemm_accum(output, (*layer).input_weights, N, M, stride, input); + i = 0; + while i < N { + *output.offset(i as isize) *= WEIGHTS_SCALE; + i += 1; + } + if (*layer).sigmoid != 0 { + i = 0; + while i < N { + *output.offset(i as isize) = sigmoid_approx(*output.offset(i as isize)); + i += 1; + } + } else { + i = 0; + while i < N { + *output.offset(i as isize) = tansig_approx(*output.offset(i as isize)); + i += 1; + } + }; +} +pub unsafe fn compute_gru(gru: *const GRULayer, state: *mut f32, input: *const f32) { + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut M: i32 = 0; + let mut stride: i32 = 0; + let mut tmp: [f32; 32] = [0.; 32]; + let mut z: [f32; 32] = [0.; 32]; + let mut r: [f32; 32] = [0.; 32]; + let mut h: [f32; 32] = [0.; 32]; + M = (*gru).nb_inputs; + N = (*gru).nb_neurons; + stride = 3 * N; + i = 0; + while i < N { + z[i as usize] = *((*gru).bias).offset(i as isize) as f32; + i += 1; + } + gemm_accum(z.as_mut_ptr(), (*gru).input_weights, N, M, stride, input); + gemm_accum( + z.as_mut_ptr(), + (*gru).recurrent_weights, + N, + N, + stride, + state, + ); + i = 0; + while i < N { + z[i as usize] = sigmoid_approx(WEIGHTS_SCALE * z[i as usize]); + i += 1; + } + i = 0; + while i < N { + r[i as usize] = *((*gru).bias).offset((N + i) as isize) as f32; + i += 1; + } + gemm_accum( + r.as_mut_ptr(), + &*((*gru).input_weights).offset(N as isize), + N, + M, + stride, + input, + ); + gemm_accum( + r.as_mut_ptr(), + &*((*gru).recurrent_weights).offset(N as isize), + N, + N, + stride, + state, + ); + i = 0; + while i < N { + r[i as usize] = sigmoid_approx(WEIGHTS_SCALE * r[i as usize]); + i += 1; + } + i = 0; + while i < N { + h[i as usize] = *((*gru).bias).offset((2 * N + i) as isize) as f32; + i += 1; + } + i = 0; + while i < N { + tmp[i as usize] = *state.offset(i as isize) * r[i as usize]; + i += 1; + } + gemm_accum( + h.as_mut_ptr(), + &*((*gru).input_weights).offset((2 * N) as isize), + N, + M, + stride, + input, + ); + gemm_accum( + h.as_mut_ptr(), + &*((*gru).recurrent_weights).offset((2 * N) as isize), + N, + N, + stride, + tmp.as_mut_ptr(), + ); + i = 0; + while i < N { + h[i as usize] = z[i as usize] * *state.offset(i as isize) + + (1 as f32 - z[i as usize]) * tansig_approx(WEIGHTS_SCALE * h[i as usize]); + i += 1; + } + i = 0; + while i < N { + *state.offset(i as isize) = h[i as usize]; + i += 1; + } +} diff --git a/vendor/unsafe-libopus/src/src/mlp_data.rs b/vendor/unsafe-libopus/src/src/mlp_data.rs new file mode 100644 index 00000000..1ef445f4 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/mlp_data.rs @@ -0,0 +1,282 @@ +use crate::src::mlp::{DenseLayer, GRULayer}; + +static mut layer0_weights: [i8; 800] = [ + -30, -9, 2, -12, 5, -1, 8, 9, 9, 8, -13, 18, -17, -34, -5, 17, -11, 0, -4, 10, 2, 10, 15, -8, + 2, -1, 0, 5, 13, -3, -16, 1, -5, 3, 7, -28, -13, 6, 36, -3, 19, -60, -17, -28, 7, -11, -30, -7, + 2, -42, -21, -3, 6, -22, 33, -9, 7, -30, 21, -14, 24, -11, -20, -18, -5, -12, 12, -49, -50, + -49, 16, 9, -37, -1, 9, 34, -13, -31, -31, 12, 16, 44, -42, 2, -9, 8, -18, -6, 9, 36, 19, 11, + 13, 12, -21, 3, -28, -12, 3, 33, 25, -14, 11, 1, -94, -39, 18, -12, -11, -15, -7, 49, 52, 10, + -43, 9, 57, 8, 21, -6, 14, -15, 44, -8, 7, -30, -13, -2, -9, 25, -2, -127, 18, -11, -52, 26, + -27, 27, 10, -10, 7, 43, 6, -24, 41, 10, -18, -27, 10, 17, 9, 10, -17, -10, 20, -6, 22, 55, 35, + -80, 36, 25, -24, -36, 15, 9, -19, 88, 19, 64, -51, -35, 17, 0, -7, 41, -16, 27, 4, 15, -1, 18, + -16, 47, -39, -54, -8, 13, -25, -20, 102, -18, -5, 44, 11, -28, 71, 2, -51, -5, 5, 2, -83, -9, + -29, 8, 21, -53, 58, -37, -7, 13, 38, 9, 34, -1, -41, 21, 4, -24, -36, -33, -21, 32, 75, -2, 1, + -68, -1, 47, -29, 32, 20, 12, -65, -87, 5, 16, -12, 24, 40, 15, 7, 19, -26, -17, 17, 6, -2, + -37, -30, -9, 32, -127, -39, 0, -31, -27, 4, -22, 23, -6, -77, 35, -61, 32, -37, -24, 13, -11, + -1, -40, -3, 17, -7, 13, 11, 59, -19, 10, 6, -18, 0, 13, 3, -6, -23, 19, 11, -17, 13, -1, -80, + 40, -53, 69, -29, -54, 0, -4, 33, -25, -2, 38, 35, 36, -15, 46, 2, -13, -16, -8, -8, 12, -24, + -9, -55, -5, -9, 32, 11, 7, 12, -18, -10, -86, -38, 54, 37, -25, 18, -43, 7, -27, -27, -54, 13, + 9, 22, 70, 6, 35, -7, 23, -15, -44, -6, 7, -66, -85, 32, 40, -19, -9, -7, 12, -15, 7, 2, 6, + -35, 11, 28, 0, 26, 14, 1, 1, 4, 12, 18, 35, 22, -18, -3, 14, -1, 7, 14, -8, -14, -3, 4, -3, + -19, -7, -1, -25, -27, 25, -26, -2, 33, -22, -27, -25, 4, -9, 7, 21, 26, -30, 10, -9, -20, 11, + 27, 10, 5, -18, 14, -4, 2, -17, -5, -7, -9, -13, 15, 29, 1, -10, -16, -10, 35, 36, -7, -22, + -44, 17, 30, 22, 21, -1, 22, -11, 32, -8, -7, 5, -10, 5, 30, -20, 29, -20, -34, 12, -4, -6, 6, + -13, 10, -5, -68, -1, 24, 9, 19, -24, -64, 31, 19, 27, -26, 75, -45, 41, 39, -42, 8, 6, 23, + -30, 16, -25, 30, 34, 8, -38, -3, 18, 16, -31, 22, -4, -9, 1, 20, 9, 38, -32, 0, -45, 0, -6, + -13, 11, -25, -32, -22, 31, -24, -11, -11, -4, -4, 20, -34, 22, 20, 9, -25, 27, -5, 28, -29, + 29, 6, 21, -6, -18, 54, 4, -46, 23, 21, -14, -31, 36, -41, -24, 4, 22, 10, 11, 7, 36, -32, -13, + -52, -17, 24, 28, -37, -36, -1, 24, 9, -38, 35, 48, 18, 2, -1, 45, 10, 39, 24, -38, 13, 8, -16, + 8, 25, 11, 7, -29, -11, 7, 20, -30, -38, -45, 14, -18, -28, -9, 65, 61, 22, -53, -38, -16, 36, + 46, 20, -39, 32, -61, -6, -6, -36, -33, -18, -28, 56, 101, 45, 11, -28, -23, -29, -61, 20, -47, + 2, 48, 27, -17, 1, 40, 1, 3, -51, 15, 35, 28, 22, 35, 53, -61, -29, 12, -6, -21, 10, 3, -20, 2, + -25, 1, -6, 31, 11, -3, 1, -10, -52, 6, 126, -105, 122, 127, -128, 127, 127, -128, 127, 108, + 12, 127, 48, -128, -36, -128, 127, 127, -128, -128, 127, 89, -128, 127, -128, -128, -128, 127, + 127, -128, -128, -93, -82, 20, 125, 65, -82, 127, 38, -74, 81, 88, -88, 79, 51, -47, -111, -26, + 14, 83, -88, -112, 24, 35, -101, 98, -99, -48, -45, 46, 83, -60, -79, 45, -20, -41, 9, 4, 52, + 54, 93, -10, 4, 13, 3, 123, 6, 94, -111, -69, -14, -31, 10, 12, 53, -79, -11, -21, -2, -44, + -72, 92, 65, -57, 56, -38, 127, -56, -128, 127, 127, -128, 86, 117, -75, -128, 127, -19, -99, + -112, 127, -128, 127, -48, 114, 118, -128, -128, 117, -17, -6, 121, -128, 127, -128, 82, 54, + -106, 127, 127, -33, 100, -39, -23, 18, -78, -34, -29, -1, -30, 127, -26, 127, -128, 126, -128, + 27, -23, -79, -120, -127, 127, 72, 66, 29, 7, -66, -56, -117, -128, +]; +static mut layer0_bias: [i8; 32] = [ + 51, -16, 1, 13, -5, -6, -16, -7, 11, -6, 106, 26, 28, -14, 21, -29, 7, 18, -18, -17, 21, -17, + -9, 20, -25, -3, -34, 48, 11, -13, -31, -20, +]; +static mut layer1_weights: [i8; 2304] = [ + 22, -1, -7, 7, 29, -27, -31, -17, -13, 33, 44, -8, 11, 33, 24, 78, 15, 19, 30, -2, -24, 5, 49, + 5, 36, 29, -14, -11, -48, -33, 21, -42, -38, -12, 55, -37, 54, -8, 1, 36, 17, 0, 51, 31, 59, 7, + -12, 53, 4, 32, -14, 48, 5, -10, -16, -8, 1, -16, -56, -24, -6, 18, -2, 23, 6, 46, -6, -10, 20, + 35, -44, -15, -49, 36, 16, 5, -7, -79, -67, 12, 70, -3, -79, -54, -85, -24, 47, -22, 33, 21, + 69, -1, 11, 22, 14, -16, -16, -22, -28, -11, 11, -41, 31, -26, -33, -19, -4, 27, 32, -50, 5, + -10, -38, -22, -8, 35, -31, 1, -41, -15, -11, 44, 28, -17, -41, -23, 17, 2, -23, -26, -13, -13, + -17, 6, 14, -31, -25, 9, -19, 39, -8, 4, 31, -1, -45, -11, -28, -92, -46, -15, 21, 118, -22, + 45, -51, 11, -20, -20, -15, 13, -21, -97, -29, -32, -23, -42, 94, 1, 23, -8, 63, -3, -46, 19, + -26, 32, -40, -74, -26, 26, -4, -13, 30, -20, -30, -25, -14, -31, -45, -43, 4, -60, -48, -12, + -34, 2, 2, 3, 13, 15, 11, 16, 5, 46, -9, -55, -16, -57, 29, 14, 38, -50, -2, -44, -11, -8, 52, + -27, -38, -7, 20, 47, 17, -59, 0, 47, 46, -63, 35, -17, 19, 33, 68, -19, 2, 15, -16, 28, -16, + -103, 26, -35, 47, -39, -60, 30, 31, -23, -52, -13, 116, 47, -25, 30, 40, 30, -22, 2, 12, -27, + -18, 31, -10, 27, -8, -66, 12, 14, 4, -26, -28, -13, 3, 13, -26, -51, 37, 5, 2, -21, 47, 3, 13, + 25, -41, -27, -8, -4, 5, -76, -33, 28, 10, 9, -46, -74, 19, 28, 25, 31, 54, -55, 68, 38, -24, + -32, 2, 4, 68, 11, -1, 99, 5, 16, -2, -74, 40, 26, -26, 33, 31, -1, -68, 14, -6, 25, 9, 29, 60, + 61, 7, -7, 0, -24, 7, 77, 4, -1, 16, -7, 13, -15, -19, 28, -31, -24, -16, 37, 24, 13, 30, 10, + -30, 11, 11, -10, 22, 60, 28, 45, -3, -40, -62, -5, -102, 9, -32, -27, -54, 21, 15, -5, 37, + -43, -11, 37, -19, 47, -64, -128, -27, -114, 21, -66, 59, 46, -3, -12, -87, -9, 4, 19, -113, + -36, 78, 57, -26, -38, -77, -10, 6, 6, -75, 25, -97, -11, 33, -46, 1, 13, -21, -33, -20, 16, + -6, -3, -11, -4, -27, 38, 8, -41, -2, -33, 18, 19, -26, 1, -29, -22, -4, -14, -55, -11, -80, + -3, 11, 34, 90, 51, 11, 17, 43, 36, 127, -32, 29, 103, 9, 27, 13, 64, 56, 70, -14, 3, -12, 10, + 37, 3, 12, -22, -10, 46, 28, 10, 20, 26, -24, 18, 9, 7, 14, 34, -5, -7, 31, -14, -56, 11, -18, + -8, -17, -7, -10, -40, 10, -33, -32, -43, 5, 9, 11, -4, 10, 50, -12, -5, 46, 9, 7, 1, 11, 15, + 91, -17, 7, -50, 23, 6, -30, -99, 0, -17, 14, 8, -10, -25, -30, -69, -62, 31, 127, 114, -23, + 101, -5, -54, -6, -22, 7, -56, 39, 18, -29, 0, 46, 8, -79, 4, -21, 18, -32, 62, -12, -8, -12, + -58, 31, -32, 17, 6, -24, 25, 24, 9, -4, -19, 45, 6, 17, -14, 5, -27, 16, -4, -41, 25, -36, 5, + 15, 12, 50, 27, 25, 23, -44, -69, -9, -19, -48, -8, 4, 12, -6, 13, -19, -30, -36, 26, 37, -1, + -3, -30, -42, -14, -10, -20, 26, -54, -27, -44, 4, 73, -26, 90, 32, -69, -29, -16, 3, 103, 15, + -17, 37, 24, -23, -31, 33, -37, -64, 25, 13, -81, -28, -32, 27, 5, -35, -23, 15, -22, 19, -7, + 9, 30, 19, -23, 27, -13, 43, 29, -29, -6, 9, -40, -33, -33, -32, 9, 11, -48, -8, -23, -52, 46, + 17, -22, -42, 35, -15, -41, 16, 34, 31, -42, -19, -11, 55, 7, -39, 89, -11, -33, 20, -14, 22, + 32, 3, -17, -6, 14, 34, 1, 55, -21, -90, -8, 18, 27, 13, -29, 21, 15, -33, -51, -9, -11, 4, + -16, -18, 23, -4, -4, 48, 1, 7, 29, -14, -12, -16, 17, 35, 8, 0, -7, -2, 9, 8, 17, -6, 53, -32, + -21, -50, 5, 99, -60, -5, -53, 10, -31, 12, -5, 7, 80, 36, 18, -31, 9, 98, 36, -63, -35, 4, + -13, -28, -24, 28, -13, 18, 16, -1, -18, -34, 10, 20, 7, 4, 29, 11, 25, -7, 36, 14, 45, 24, 1, + -16, 30, 6, 35, -6, -11, -24, 13, -1, 27, 39, 20, 48, -11, -4, -13, 28, 11, -31, -18, 31, -29, + 22, -2, -20, -16, 5, 30, -12, -28, -3, 93, -16, 23, 18, -29, 6, -54, -37, 28, -3, -3, -47, -3, + -36, -55, -3, 41, -10, 47, -2, 23, 42, -7, -71, -27, 83, -64, 7, -24, 8, 26, -17, 15, 12, 31, + -30, -38, -13, -33, -56, 4, -17, 20, 18, 1, -30, -5, -6, -31, -14, -37, 0, 22, 10, -30, 37, + -17, 18, 6, 5, 23, -36, -32, 14, 18, -13, -61, -52, -69, 44, -30, 16, 18, -4, -25, 14, 81, 26, + -8, -23, -59, 52, -104, 17, 119, -32, 26, 17, 1, 23, 45, 29, -64, -57, -14, 73, 21, -13, -13, + 9, -68, -7, -52, 3, 24, -39, 44, -15, 27, 14, 19, -9, -28, -11, 5, 3, -34, -2, 2, 22, -6, -23, + 4, 3, 13, -22, -13, -10, -18, 29, 6, 44, -13, -24, -8, 2, 30, 14, 43, 6, 17, -73, -6, -7, 20, + -80, -7, -7, -28, 15, -69, -38, -5, -100, -35, 15, -79, 23, 29, -18, -27, 21, -66, -37, 8, -22, + -39, 48, 4, -13, 1, -9, 11, -29, 22, 6, -49, 32, -14, 47, -18, -4, 44, -52, -74, 43, 30, 23, + -14, 5, 0, -27, 4, -7, 10, -4, 10, 1, -16, 11, -18, -2, -5, 2, -11, 0, -20, -4, 38, 74, 59, 39, + 64, -10, 26, -3, -40, -68, 3, -30, -51, 8, -19, -27, -46, 51, 52, 54, 36, 90, 92, 14, 13, -5, + 0, 16, -62, 16, 11, -47, -37, -6, -5, 21, 54, -57, 32, 42, -6, 62, -9, 16, 21, 24, 9, -10, -4, + 33, 50, 13, -15, 1, -35, -48, 18, -11, -17, -67, -13, 21, 38, -44, 36, -16, 29, 17, 5, -10, 18, + 17, -32, 2, 8, 22, -56, -15, -32, 40, 43, 19, 46, -7, -100, -96, 19, 53, 24, 21, -26, -48, + -101, -82, 61, 38, -85, -28, -34, -1, 63, -5, -5, 39, 39, -38, 32, -12, -28, 20, 40, -8, 2, 31, + 12, -35, -13, 20, -25, 30, 8, 3, -13, -9, -20, 2, -13, 24, 37, -10, 33, 6, 20, -16, -24, -6, + -6, -19, -5, 22, 21, 10, 11, -4, -39, -1, 6, 49, 41, -15, -57, 21, -62, 77, -69, -13, 0, -74, + 1, -7, -38, -8, 6, 63, 28, 4, 26, -52, 82, 63, 13, 45, -33, 44, -52, -65, -21, -46, -49, 64, + -17, 32, 24, 68, -39, -16, -5, -26, 28, 5, -61, -28, 2, 24, 11, -12, -33, 9, -37, -3, -28, 22, + -37, -12, 19, 0, -18, -2, 14, 1, 4, 8, -9, -2, 43, -17, -2, -66, -31, 56, -40, -87, -36, -2, + -4, -42, -45, -1, 31, -43, -15, 27, 63, -11, 32, -10, -33, 27, -19, 4, 15, -26, -34, 29, -4, + -39, -65, 14, -20, -21, -17, -36, 13, 59, 47, -38, -33, 13, -37, -8, -37, -7, -6, -76, -31, + -12, -46, 7, 24, -21, -30, -14, 9, 15, -12, -13, 47, -27, -25, -1, -39, 0, 20, -9, 6, 7, 4, 3, + 7, 39, 50, 22, -7, 14, -20, 1, 70, -28, 29, -41, 10, -16, -5, -28, -2, -37, 32, -18, 17, 62, + -11, -20, -50, 36, 21, -62, -12, -56, 52, 50, 17, 3, 48, 44, -41, -25, 3, 16, -3, 0, 33, -6, + 15, 27, 34, -25, 22, 9, 17, -11, 36, 16, -2, 12, 21, -52, 45, -2, -10, 46, 21, -18, 67, -28, + -13, 30, 37, 42, 16, -9, 11, 75, 7, -64, -40, -10, 29, 57, -23, 5, 53, -77, 3, -17, -5, 47, + -55, -35, -36, -13, 52, -53, -71, 52, -111, -23, -26, -28, 29, -43, 55, -19, 43, -19, 54, -12, + -33, -44, -39, -19, -10, -31, -10, 21, 38, -57, -20, 2, -25, 8, -6, 50, 12, 15, 25, -25, 15, + -30, -6, 9, 25, 37, 19, -4, 31, -22, 2, 4, 2, 36, 7, 3, -34, -80, 36, -10, -2, -5, 31, -36, 49, + -70, 20, -36, 21, 24, 25, -46, -51, 36, -58, -48, -40, -10, 55, 71, 47, 10, -1, 1, 2, -46, -68, + 16, 13, 0, -74, -29, 73, -52, -18, -11, 7, -44, -82, -32, -70, -28, -1, -39, -68, -6, -41, 12, + -22, -16, 40, -11, -25, 51, -9, 21, 4, 4, -34, 7, -78, 16, 6, -38, -30, -2, -44, 32, 0, 22, 64, + 5, -72, -2, -14, -10, -16, -8, -25, 12, 102, -58, 37, -10, -23, 15, 49, 7, -7, 2, -20, -32, 45, + -6, 48, 28, 30, 33, -1, 22, -6, 30, 65, -17, 29, 74, 37, -26, -10, 15, -24, 19, -66, 22, -10, + -31, -1, -18, -9, 11, 37, -4, 45, 5, 41, 17, 1, 1, 24, -58, 41, 5, -51, 14, 8, 43, 16, -10, -1, + 45, 32, -64, 3, -33, -25, -3, -27, -68, 12, 23, -11, -13, -37, -40, 4, -21, -12, 32, -23, -19, + 76, 41, -23, -24, -44, -65, -1, -15, 1, 71, 63, 5, 20, -3, 21, -23, 31, -32, 18, -2, 27, 31, + 46, -5, -39, -5, -35, 18, -18, -40, -10, 3, 12, 2, -2, -22, 40, 5, -6, 60, 36, 3, 29, -27, 10, + 25, -54, 5, 26, 39, 35, -24, -37, 30, -91, 28, -4, -21, -27, -39, -6, 5, 12, -128, 38, -16, 29, + -95, -29, 82, -2, 35, 2, 12, 8, -22, 10, 80, -47, 2, -25, -73, -79, 16, -30, -32, -66, 48, 21, + -45, -11, -47, 14, -27, -17, -7, 15, -44, -14, -44, -26, -32, 26, -23, 17, -7, -28, 26, -6, 28, + 6, -26, 2, 13, -14, -23, -14, 19, 46, 16, 2, -33, -21, 28, -17, -42, 44, -37, 1, -39, 28, 84, + -46, 15, 10, 13, -44, 72, -26, 26, 32, -28, -12, -83, 2, 10, -30, -44, -10, -28, 53, 45, 65, 0, + -25, 57, 36, -33, 6, 29, 44, -53, 11, 19, -2, -27, 35, 32, 49, 4, 23, 38, 36, 24, 10, 51, -39, + 4, -7, 26, 37, -35, 11, -47, -18, 28, 16, -35, 42, 17, -21, -41, 28, 14, -12, 11, -45, 7, -43, + -15, 18, -5, 38, -40, -50, -30, -21, 9, -98, 13, 12, 23, 75, -56, -7, -3, -4, -1, -34, 12, -49, + 11, 26, -18, -28, -17, 33, 13, -14, 40, 24, -72, -37, 10, 17, -6, 22, 16, 16, -6, -12, -30, + -14, 10, 40, -23, 12, 15, -3, -15, 13, -56, -4, -30, 1, -3, -17, 27, 50, -5, 64, -36, -19, 7, + 29, 22, 25, 9, -16, -58, -69, -40, -61, -71, -14, 42, 93, 26, 11, -6, -58, -11, 70, -52, 19, 9, + -30, -33, 11, -37, -47, -21, -22, -40, 10, 47, 4, -23, 17, 48, 41, -48, 14, 10, 15, 34, -23, + -2, -47, 23, -32, -13, -10, -26, -26, -4, 16, 38, -14, 0, -12, -7, -7, 20, 44, -1, -32, -27, + -16, 4, -6, -18, 14, 5, 4, -29, 28, 7, -7, 15, -11, -20, -45, -36, 16, 84, 34, -59, -30, 22, + 126, 8, 68, 79, -17, 21, -68, 37, 5, 15, 63, 49, 127, -90, 85, 43, 7, 16, 9, 6, -45, -57, -43, + 57, 11, -23, -11, -29, 60, -26, 0, 7, 42, -24, 10, 23, -25, 8, -7, -40, 19, -17, 35, 4, 27, + -39, -91, 27, -36, 34, 2, 16, -24, 25, 7, -21, 5, 17, 10, -22, -30, 9, -17, -61, -26, 33, 21, + 58, -51, -14, 69, -38, 20, 7, 80, -4, -65, -6, -27, 53, -12, 47, -1, -15, 1, 60, 102, -79, -4, + 12, 9, 22, 37, -8, -4, 37, 2, -3, -15, -16, -11, -5, 19, -6, -43, 20, -25, -18, 10, -27, 0, + -28, -27, -11, 10, -18, -2, -4, -16, 26, 14, -6, 7, -6, 1, 53, -2, -29, 23, 9, -30, -6, -4, -6, + 56, 70, 0, -33, -20, -17, -9, -24, 46, -5, -105, 47, -46, -51, 20, 20, -53, -81, -1, -7, 75, + -5, -21, -65, 12, -52, 22, -50, -12, 49, 54, 76, -81, 10, 45, -41, -59, 18, -19, 25, 14, -31, + -53, -5, 12, 31, 84, -23, 2, 7, 2, 10, -32, 39, -2, -12, 1, -9, 0, -10, -11, 9, 15, -8, -2, 2, + -1, 10, 14, -5, -40, 19, -7, -7, 26, -4, 2, 1, -27, 35, 32, 21, -31, 26, 43, -9, 4, -32, 40, + -62, -52, 36, 22, 38, 22, 36, -96, 6, -10, -23, -49, 15, -33, -18, -3, 0, 41, 21, -19, 21, 23, + -39, -23, -6, 6, 47, 56, 4, 74, 0, -98, 29, -47, -14, -36, 21, -22, 22, 16, 13, 12, 16, -5, 13, + 17, -13, -15, 1, -34, -26, 26, 12, 32, 27, 13, -67, 27, 2, 8, 10, 18, 16, 20, -17, -17, 57, + -64, 5, 14, 19, 31, -18, -44, -46, -16, 4, -25, 17, -126, -24, 39, 4, 8, 55, -25, -34, 39, -16, + 3, 9, 71, 72, -31, -55, 6, 10, -25, 32, -85, -21, 18, -8, 15, 12, -27, -7, 1, -21, -2, -5, 48, + -16, 18, 1, -22, -26, 16, 14, -31, 27, -6, -15, -21, 4, -14, 18, -36, +]; +static mut layer1_recur_weights: [i8; 1728] = [ + 20, 67, -99, 12, 41, -25, 49, -44, 35, 81, 110, 47, 34, -66, -14, 14, -60, 34, 29, -73, 10, 41, + 35, 89, 7, -35, 22, 7, 27, -20, -6, 56, 26, 66, 6, 33, -55, 53, 1, -21, 14, 17, 68, 55, 59, 0, + 18, -9, 5, -41, 6, -5, -114, -12, 29, 42, -23, 10, 81, -27, 20, -53, -30, -62, 40, 95, 25, -4, + 3, 18, -8, -15, -29, -82, 2, -57, -3, -61, -29, -29, 49, 2, -55, 5, -69, -99, -49, -51, 6, -25, + 12, 89, 44, -33, 5, 41, 1, 23, -37, -37, -28, -48, 3, 4, -41, -30, -57, -35, -39, -1, -13, -56, + -5, 50, 49, 41, -4, -4, 33, -22, -1, 33, 34, 18, 40, -42, 12, 1, -6, -2, 18, 17, 39, 44, 11, + 65, -60, -45, 10, 91, 21, 9, -62, -11, 8, 69, 37, 24, -30, 21, 26, -27, 1, -28, 24, 66, -8, 6, + -71, 34, 24, 44, 58, -78, -19, 57, 17, -60, 1, 12, -3, -1, -40, 22, 11, -5, 25, 12, 1, 72, 79, + 7, -50, 23, 18, 13, 21, -11, -20, 5, 77, -94, 24, 15, 57, -51, 3, 36, 53, -1, 4, 14, 30, -31, + 22, 40, 32, -11, -34, -36, -59, 58, 25, 21, -54, -23, 40, 46, 18, 0, 12, 54, -96, -99, -59, 5, + 119, -38, 50, 55, 12, -16, 67, 0, 34, 35, 39, 35, -1, 69, 24, 27, -30, -35, -4, -70, 2, -44, + -7, -6, 19, -9, 60, 44, -21, -10, 37, 43, -16, -3, 30, -15, -65, 31, -55, 18, -98, 76, 64, 25, + 24, -18, -7, -68, -10, 38, 27, -60, 36, 33, 16, 30, 34, -39, -37, 31, 12, 53, -54, 14, -26, + -49, -128, -13, -5, -22, -11, -85, 55, -8, -51, -11, -33, -10, -31, -76, -41, 23, 44, -40, -54, + -127, -101, 19, -23, -15, 15, 27, 58, -60, 8, 14, -33, 1, 48, -9, -11, -123, 3, 53, 23, 4, -28, + 22, 2, -29, -67, 36, 12, 7, 55, -21, 88, 20, -1, -21, -17, 3, 41, 32, -10, -14, -5, -57, 67, + 57, 21, 23, -2, -27, -73, -24, 120, 21, 18, -35, 42, -7, 3, -45, -25, 76, -34, 50, 11, -54, + -91, 3, -113, -20, -5, 47, 15, -47, 17, 27, -3, -26, -7, 10, 7, 74, -40, 64, -7, -5, -24, -49, + -24, -3, -10, 27, -17, -8, -3, 14, -27, 33, 13, 39, 28, -7, -38, 29, 16, 44, 19, 55, -3, 9, + -13, -57, 43, 43, 31, 0, -93, -17, 19, -56, 4, -12, -25, 37, -85, -13, -118, 33, -17, 56, 71, + -80, -4, 6, -11, -18, 47, -52, 25, 9, 48, -107, 1, 21, 20, -3, 10, -16, -4, 24, 17, 31, -61, + -18, -50, 24, -10, 12, 71, 26, 11, -3, 4, 1, 0, -7, -40, 18, 38, -34, 38, 17, 8, -34, 2, 21, + 123, -32, -26, 43, 14, -34, -1, -9, 37, -16, 6, -17, -62, 68, 22, 17, 11, -75, 33, -80, 62, -9, + -75, 76, 36, -41, -8, -40, -11, -71, 40, -39, 62, -49, -81, 16, -9, -52, 52, 61, 17, -103, -27, + -10, -8, -54, -57, 21, 23, -16, -52, 36, 18, 10, -5, 8, 15, -29, 5, -19, -37, 8, -53, 6, 19, + -37, 38, -17, 48, 10, 0, 81, 46, 70, -29, 101, 11, 44, -44, -3, 24, 11, 3, 14, -9, 11, 14, -45, + 13, 46, -3, -57, 68, 44, 63, 98, 25, -28, -23, 15, 32, -10, 53, -6, -2, -9, -6, 16, -107, -11, + -11, -28, 59, 57, -22, 38, 42, 83, 27, 5, 29, -30, 12, -21, -13, 31, 38, -21, 58, -10, -10, + -15, -2, -5, 11, 12, -73, -28, -38, 22, 2, -25, 73, -52, -12, -55, 32, -63, 21, 51, 33, 52, + -26, 55, -26, -26, 57, -32, -4, -52, -61, 21, -33, -91, -51, 69, -90, -53, -38, -44, 12, -76, + -20, 77, -45, -7, 86, 43, -109, -33, -105, -40, -121, -10, 0, -72, 45, -51, -75, -49, -38, -1, + -62, 18, -1, 30, -44, -14, -10, -67, 40, -10, -34, 46, -64, -32, 29, -13, 33, 3, -32, -5, 28, + -27, -25, 93, 24, 68, -40, 57, 23, -3, -21, -58, 17, -39, -17, -22, -89, 11, 18, -46, 27, 24, + 46, 127, 61, 87, 31, 127, -36, 47, -23, 47, 127, -24, 110, 122, 30, 100, 0, 96, -12, 6, 50, 44, + -13, 73, 4, 55, -11, -15, 49, 42, -6, 20, -35, 58, 18, 38, 42, 72, 19, -21, 11, 9, -37, 7, 29, + 31, 16, -17, 13, -50, 19, 5, -23, 51, -16, -5, 4, -24, 76, 10, -53, -28, -7, -65, 74, 40, -16, + -29, 32, -16, -49, -35, -3, 59, -96, -50, -43, -43, -61, -15, -8, -36, -34, -33, -14, 11, -3, + -39, 4, -114, -123, -11, -49, -21, 14, -56, 1, 43, -63, 26, 40, 18, -10, -26, -14, -15, -35, + -35, -11, 32, -44, -67, 2, 22, 7, 3, -9, -30, -51, -28, 28, 6, -22, 16, 34, -25, -52, -54, -8, + -6, 5, 8, 20, -16, -17, -44, 27, 3, 31, -5, -48, -1, -3, 116, 11, 71, -31, -47, 109, 50, -22, + -12, -57, 32, 66, 8, -25, -93, -54, -10, 19, -76, -34, 97, 48, -36, -18, -30, -39, -26, -12, + 28, 14, 12, -12, -31, 38, 2, 10, 4, -40, 20, 16, -61, 2, 64, 39, 5, 15, 33, 40, -61, -49, 93, + -10, 33, 28, -11, -27, -18, 39, -62, -6, -6, 62, 11, -8, 38, -67, 12, 27, 39, -27, 123, -18, + -6, -65, 83, -64, 20, 19, -11, 33, 24, 17, 56, 78, 7, -15, 54, -101, -9, 115, -96, 50, 51, 35, + 34, 27, 37, -40, -11, 8, -36, 42, -45, 2, -23, 0, 67, -8, -9, -13, 50, -14, -27, 4, 0, -8, -14, + 30, -9, 29, 15, 9, -38, 37, -8, 50, -46, 54, 41, -11, -8, -11, -26, 39, 45, 14, -26, -17, -27, + 69, 38, 39, 98, 66, 0, 42, 123, -101, -19, -83, 117, -32, 56, 10, 12, -88, 79, -53, 56, 63, 95, + -62, 9, 36, -13, -79, -16, 37, -46, 35, -34, 14, 17, -54, 5, 21, -7, 7, 63, 56, 15, 27, -76, + -25, 4, -26, -63, 28, -67, -52, 43, -47, -70, 40, -12, 40, -66, -37, 0, 35, 37, -53, 4, -17, + -51, 11, 21, 14, -34, -4, 24, -42, 29, 22, 7, 28, 12, 37, 39, -39, -19, 65, -60, -50, -2, 1, + 82, 39, 19, -23, -43, -22, -67, -35, -34, 32, 102, 81, 127, 36, 67, -45, 1, -67, -52, -4, 35, + 20, 28, 71, 86, -35, -9, -83, -34, 12, 9, -23, 2, 14, 28, -23, 7, -25, 45, 7, 17, -37, 0, -19, + 31, 26, 40, -27, -16, 17, 5, -21, 23, 24, 96, -55, 52, -19, -14, -6, 1, 50, -34, 86, -53, 38, + 2, -52, -36, -13, 60, -85, -120, 32, 7, -12, 22, 70, -7, -94, 38, -76, -31, -20, 15, -28, 7, 6, + 40, 53, 88, 3, 38, 18, -8, -22, -23, 51, 37, -9, 13, -32, 25, -21, 27, 31, 20, 18, -9, -13, 1, + 21, -24, -13, 39, 15, -11, -29, -36, 18, 15, 8, 27, 21, -94, -1, -22, 49, 66, -1, 6, -3, -40, + -18, 6, 28, 12, 33, -59, 62, 60, -48, 90, -1, 108, 9, 18, -2, 27, 77, -65, 82, -48, -38, -19, + -11, 127, 50, 66, 18, -13, -22, 60, -38, 40, -14, -26, -13, 38, 67, 57, 30, 33, 26, 36, 38, + -17, 27, -28, 20, 12, -64, 18, 5, -33, -27, 13, -26, 32, 35, -5, -48, -14, 92, 43, -47, -14, + 40, 11, 51, 66, 22, -63, -16, -61, 4, -28, 27, 20, -33, -30, -21, -29, -53, 31, -40, 24, 43, + -4, -19, 21, 67, 20, 100, -16, -93, 78, -6, -18, -52, -37, -9, 66, -31, -8, 26, 18, 4, 24, -22, + 17, -2, -13, 27, 0, 8, -18, -25, 5, -21, -24, -7, 18, -93, 21, 7, 2, -75, 69, 50, -5, -15, -17, + 60, -42, 55, 1, -4, 3, 10, 46, 16, -13, 45, -7, -10, -44, -108, 49, 2, -15, -64, -12, -72, 32, + -38, -45, 10, -54, 13, -13, -27, -36, -64, 58, -62, -101, 88, -86, -71, -39, -9, -128, 32, 15, + -4, 54, -16, -39, -26, -36, 46, 48, -64, -10, 19, 30, -13, 34, -8, 50, 60, -22, -6, -11, -30, + 5, 50, 32, 56, 0, 25, 6, 68, 11, -29, 45, -9, -12, 4, 1, 18, -49, 0, -38, -19, 90, 29, 35, 51, + 8, -48, 96, -1, -12, -9, -32, -63, -65, -7, 38, 89, 28, -85, -28, -23, -25, -128, 56, 79, -36, + 99, -6, -37, 7, -13, -69, -46, -29, 25, 64, -21, 17, 1, 42, -66, 1, 80, 26, -32, 21, 15, 15, 6, + 6, -10, 15, 127, 5, 38, 27, 87, -57, -25, 11, 72, -21, -5, 11, -13, -66, 78, 36, -3, 41, -21, + 8, -33, 23, 73, 28, 57, -25, -5, 4, -22, -47, 15, 4, -57, -72, 33, 1, 18, 2, 53, -71, -99, -21, + -3, -111, 108, 71, -14, 82, 25, 61, -48, 5, 9, -51, -20, -25, -3, 14, -33, 14, -3, -34, 22, 12, + -19, -38, -16, 2, 21, 16, 26, -31, 75, 44, -31, 16, 26, 66, 17, -9, -22, -22, 22, -44, 22, 27, + 2, 58, -14, 10, -73, -42, 55, -25, -61, 72, -1, 30, -58, -25, 63, 26, -48, -40, 26, -30, 60, 8, + -17, -1, -18, -20, 43, -20, -4, -28, 127, -106, 29, 70, 64, -27, 39, -33, -5, -88, -40, -52, + 26, 44, -17, 23, 2, -49, 22, -9, -8, 86, 49, -43, -60, 1, 10, 45, 36, -53, -4, 33, 38, 48, -72, + 1, 19, 21, -65, 4, -5, -62, 27, -25, 17, -6, 6, -45, -39, -46, 4, 26, 127, -9, 18, -33, -18, + -3, 33, 2, -5, 15, -26, -22, -117, -63, -17, -59, 61, -74, 7, -47, -58, -128, -67, 15, -16, + -128, 12, 2, 20, 9, -48, -40, 43, 3, -40, -16, -38, -6, -22, -28, -16, -59, -22, 6, -5, 11, + -12, -66, -40, 27, -62, -44, -19, 38, -3, 39, -8, 40, -24, 13, 21, 50, -60, -22, 53, -29, -6, + 1, 22, -59, 0, 17, -39, 115, +]; +static mut layer1_bias: [i8; 72] = [ + -42, 20, 16, 0, 105, 60, 1, -97, 24, 60, 18, 13, 62, 25, 127, 34, 79, 55, 118, 127, 95, 31, -4, + 87, 21, 12, 2, -14, 18, 23, 8, 17, -1, -8, 5, 4, 24, 37, 21, 13, 36, 13, 17, 18, 37, 30, 33, 1, + 8, -16, -11, -5, -31, -3, -5, 0, 6, 3, 58, -7, -1, -16, 5, -13, 16, 10, -2, -14, 11, -4, 3, + -11, +]; +static mut layer2_weights: [i8; 48] = [ + -113, -88, 31, -128, -126, -61, 85, -35, 118, -128, -61, 127, -128, -17, -128, 127, 104, -9, + -128, 33, 45, 127, 5, 83, 84, -128, -85, -128, -45, 48, -53, -128, 46, 127, -17, 125, 117, -41, + -117, -91, -127, -68, -1, -89, -80, 32, 106, 7, +]; +static mut layer2_bias: [i8; 2] = [14, 117]; +pub static mut layer0: DenseLayer = unsafe { + { + let init = DenseLayer { + bias: layer0_bias.as_ptr(), + input_weights: layer0_weights.as_ptr(), + nb_inputs: 25, + nb_neurons: 32, + sigmoid: 0, + }; + init + } +}; +pub static mut layer1: GRULayer = unsafe { + { + let init = GRULayer { + bias: layer1_bias.as_ptr(), + input_weights: layer1_weights.as_ptr(), + recurrent_weights: layer1_recur_weights.as_ptr(), + nb_inputs: 32, + nb_neurons: 24, + }; + init + } +}; +pub static mut layer2: DenseLayer = unsafe { + { + let init = DenseLayer { + bias: layer2_bias.as_ptr(), + input_weights: layer2_weights.as_ptr(), + nb_inputs: 24, + nb_neurons: 2, + sigmoid: 1, + }; + init + } +}; diff --git a/vendor/unsafe-libopus/src/src/opus.rs b/vendor/unsafe-libopus/src/src/opus.rs new file mode 100644 index 00000000..99a4dc02 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus.rs @@ -0,0 +1,367 @@ +pub mod stddef_h { + pub const NULL: i32 = 0; +} +pub use self::stddef_h::NULL; +use crate::src::opus_defines::{OPUS_BAD_ARG, OPUS_INVALID_PACKET}; + +pub unsafe fn opus_pcm_soft_clip(mut _x: *mut f32, N: i32, C: i32, declip_mem: *mut f32) { + let mut c: i32 = 0; + let mut i: i32 = 0; + let mut x: *mut f32 = 0 as *mut f32; + if C < 1 || N < 1 || _x.is_null() || declip_mem.is_null() { + return; + } + i = 0; + while i < N * C { + *_x.offset(i as isize) = if -2.0f32 + > (if 2.0f32 < *_x.offset(i as isize) { + 2.0f32 + } else { + *_x.offset(i as isize) + }) { + -2.0f32 + } else if 2.0f32 < *_x.offset(i as isize) { + 2.0f32 + } else { + *_x.offset(i as isize) + }; + i += 1; + } + c = 0; + while c < C { + let mut a: f32 = 0.; + let mut x0: f32 = 0.; + let mut curr: i32 = 0; + x = _x.offset(c as isize); + a = *declip_mem.offset(c as isize); + i = 0; + while i < N { + if *x.offset((i * C) as isize) * a >= 0 as f32 { + break; + } + *x.offset((i * C) as isize) = *x.offset((i * C) as isize) + + a * *x.offset((i * C) as isize) * *x.offset((i * C) as isize); + i += 1; + } + curr = 0; + x0 = *x.offset(0 as isize); + loop { + let mut start: i32 = 0; + let mut end: i32 = 0; + let mut maxval: f32 = 0.; + let mut special: i32 = 0; + let mut peak_pos: i32 = 0; + i = curr; + while i < N { + if *x.offset((i * C) as isize) > 1 as f32 || *x.offset((i * C) as isize) < -1 as f32 + { + break; + } + i += 1; + } + if i == N { + a = 0 as f32; + break; + } else { + peak_pos = i; + end = i; + start = end; + maxval = (*x.offset((i * C) as isize)).abs(); + while start > 0 + && *x.offset((i * C) as isize) * *x.offset(((start - 1) * C) as isize) + >= 0 as f32 + { + start -= 1; + } + while end < N + && *x.offset((i * C) as isize) * *x.offset((end * C) as isize) >= 0 as f32 + { + if (*x.offset((end * C) as isize)).abs() > maxval { + maxval = (*x.offset((end * C) as isize)).abs(); + peak_pos = end; + } + end += 1; + } + special = (start == 0 + && *x.offset((i * C) as isize) * *x.offset(0 as isize) >= 0 as f32) + as i32; + a = (maxval - 1 as f32) / (maxval * maxval); + a += a * 2.4e-7f32; + if *x.offset((i * C) as isize) > 0 as f32 { + a = -a; + } + i = start; + while i < end { + *x.offset((i * C) as isize) = *x.offset((i * C) as isize) + + a * *x.offset((i * C) as isize) * *x.offset((i * C) as isize); + i += 1; + } + if special != 0 && peak_pos >= 2 { + let mut delta: f32 = 0.; + let mut offset: f32 = x0 - *x.offset(0 as isize); + delta = offset / peak_pos as f32; + i = curr; + while i < peak_pos { + offset -= delta; + *x.offset((i * C) as isize) += offset; + *x.offset((i * C) as isize) = if -1.0f32 + > (if 1.0f32 < *x.offset((i * C) as isize) { + 1.0f32 + } else { + *x.offset((i * C) as isize) + }) { + -1.0f32 + } else if 1.0f32 < *x.offset((i * C) as isize) { + 1.0f32 + } else { + *x.offset((i * C) as isize) + }; + i += 1; + } + } + curr = end; + if curr == N { + break; + } + } + } + *declip_mem.offset(c as isize) = a; + c += 1; + } +} +pub unsafe fn encode_size(size: i32, data: *mut u8) -> i32 { + if size < 252 { + *data.offset(0 as isize) = size as u8; + return 1; + } else { + *data.offset(0 as isize) = (252 + (size & 0x3)) as u8; + *data.offset(1 as isize) = (size - *data.offset(0 as isize) as i32 >> 2) as u8; + return 2; + }; +} +unsafe fn parse_size(data: *const u8, len: i32, size: *mut i16) -> i32 { + if len < 1 { + *size = -1 as i16; + return -1; + } else if (*data.offset(0 as isize) as i32) < 252 { + *size = *data.offset(0 as isize) as i16; + return 1; + } else if len < 2 { + *size = -1 as i16; + return -1; + } else { + *size = (4 * *data.offset(1 as isize) as i32 + *data.offset(0 as isize) as i32) as i16; + return 2; + }; +} +pub unsafe fn opus_packet_get_samples_per_frame(data: *const u8, Fs: i32) -> i32 { + let mut audiosize: i32 = 0; + if *data.offset(0 as isize) as i32 & 0x80 != 0 { + audiosize = *data.offset(0 as isize) as i32 >> 3 & 0x3; + audiosize = (Fs << audiosize) / 400; + } else if *data.offset(0 as isize) as i32 & 0x60 == 0x60 { + audiosize = if *data.offset(0 as isize) as i32 & 0x8 != 0 { + Fs / 50 + } else { + Fs / 100 + }; + } else { + audiosize = *data.offset(0 as isize) as i32 >> 3 & 0x3; + if audiosize == 3 { + audiosize = Fs * 60 / 1000; + } else { + audiosize = (Fs << audiosize) / 100; + } + } + return audiosize; +} +pub unsafe fn opus_packet_parse_impl( + mut data: *const u8, + mut len: i32, + self_delimited: i32, + out_toc: *mut u8, + frames: *mut *const u8, + size: *mut i16, + payload_offset: *mut i32, + packet_offset: *mut i32, +) -> i32 { + let mut i: i32 = 0; + let mut bytes: i32 = 0; + let mut count: i32 = 0; + let mut cbr: i32 = 0; + let mut ch: u8 = 0; + let mut toc: u8 = 0; + let mut framesize: i32 = 0; + let mut last_size: i32 = 0; + let mut pad: i32 = 0; + let data0: *const u8 = data; + if size.is_null() || len < 0 { + return OPUS_BAD_ARG; + } + if len == 0 { + return OPUS_INVALID_PACKET; + } + framesize = opus_packet_get_samples_per_frame(data, 48000); + cbr = 0; + let fresh0 = data; + data = data.offset(1); + toc = *fresh0; + len -= 1; + last_size = len; + match toc as i32 & 0x3 { + 0 => { + count = 1; + } + 1 => { + count = 2; + cbr = 1; + if self_delimited == 0 { + if len & 0x1 != 0 { + return OPUS_INVALID_PACKET; + } + last_size = len / 2; + *size.offset(0 as isize) = last_size as i16; + } + } + 2 => { + count = 2; + bytes = parse_size(data, len, size); + len -= bytes; + if (*size.offset(0 as isize) as i32) < 0 || *size.offset(0 as isize) as i32 > len { + return OPUS_INVALID_PACKET; + } + data = data.offset(bytes as isize); + last_size = len - *size.offset(0 as isize) as i32; + } + _ => { + if len < 1 { + return OPUS_INVALID_PACKET; + } + let fresh1 = data; + data = data.offset(1); + ch = *fresh1; + count = ch as i32 & 0x3f; + if count <= 0 || framesize * count > 5760 { + return OPUS_INVALID_PACKET; + } + len -= 1; + if ch as i32 & 0x40 != 0 { + let mut p: i32 = 0; + loop { + let mut tmp: i32 = 0; + if len <= 0 { + return OPUS_INVALID_PACKET; + } + let fresh2 = data; + data = data.offset(1); + p = *fresh2 as i32; + len -= 1; + tmp = if p == 255 { 254 } else { p }; + len -= tmp; + pad += tmp; + if !(p == 255) { + break; + } + } + } + if len < 0 { + return OPUS_INVALID_PACKET; + } + cbr = (ch as i32 & 0x80 == 0) as i32; + if cbr == 0 { + last_size = len; + i = 0; + while i < count - 1 { + bytes = parse_size(data, len, size.offset(i as isize)); + len -= bytes; + if (*size.offset(i as isize) as i32) < 0 + || *size.offset(i as isize) as i32 > len + { + return OPUS_INVALID_PACKET; + } + data = data.offset(bytes as isize); + last_size -= bytes + *size.offset(i as isize) as i32; + i += 1; + } + if last_size < 0 { + return OPUS_INVALID_PACKET; + } + } else if self_delimited == 0 { + last_size = len / count; + if last_size * count != len { + return OPUS_INVALID_PACKET; + } + i = 0; + while i < count - 1 { + *size.offset(i as isize) = last_size as i16; + i += 1; + } + } + } + } + if self_delimited != 0 { + bytes = parse_size(data, len, size.offset(count as isize).offset(-(1 as isize))); + len -= bytes; + if (*size.offset((count - 1) as isize) as i32) < 0 + || *size.offset((count - 1) as isize) as i32 > len + { + return OPUS_INVALID_PACKET; + } + data = data.offset(bytes as isize); + if cbr != 0 { + if *size.offset((count - 1) as isize) as i32 * count > len { + return OPUS_INVALID_PACKET; + } + i = 0; + while i < count - 1 { + *size.offset(i as isize) = *size.offset((count - 1) as isize); + i += 1; + } + } else if bytes + *size.offset((count - 1) as isize) as i32 > last_size { + return OPUS_INVALID_PACKET; + } + } else { + if last_size > 1275 { + return OPUS_INVALID_PACKET; + } + *size.offset((count - 1) as isize) = last_size as i16; + } + if !payload_offset.is_null() { + *payload_offset = data.offset_from(data0) as i64 as i32; + } + i = 0; + while i < count { + if !frames.is_null() { + let ref mut fresh3 = *frames.offset(i as isize); + *fresh3 = data; + } + data = data.offset(*size.offset(i as isize) as i32 as isize); + i += 1; + } + if !packet_offset.is_null() { + *packet_offset = pad + data.offset_from(data0) as i64 as i32; + } + if !out_toc.is_null() { + *out_toc = toc; + } + return count; +} +pub unsafe fn opus_packet_parse( + data: *const u8, + len: i32, + out_toc: *mut u8, + frames: *mut *const u8, + size: *mut i16, + payload_offset: *mut i32, +) -> i32 { + return opus_packet_parse_impl( + data, + len, + 0, + out_toc, + frames, + size, + payload_offset, + NULL as *mut i32, + ); +} diff --git a/vendor/unsafe-libopus/src/src/opus_decoder.rs b/vendor/unsafe-libopus/src/src/opus_decoder.rs new file mode 100644 index 00000000..97520a01 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_decoder.rs @@ -0,0 +1,1122 @@ +use crate::externs::{free, malloc}; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; +} +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub mod stack_alloc_h { + pub const ALLOC_NONE: i32 = 1; + #[inline] + pub unsafe fn _opus_false() -> i32 { + return 0; + } +} +pub use self::arch_h::{opus_val16, opus_val32}; +pub use self::cpu_support_h::opus_select_arch; +pub use self::stack_alloc_h::{_opus_false, ALLOC_NONE}; +pub use self::stddef_h::{size_t, NULL}; +use crate::celt::celt::CELT_SET_SIGNALLING_REQUEST; +use crate::celt::celt_decoder::{ + celt_decode_with_ec, celt_decoder_get_size, celt_decoder_init, OpusCustomDecoder, +}; +use crate::celt::entcode::ec_tell; +use crate::celt::entdec::ec_dec; +use crate::celt::entdec::{ec_dec_bit_logp, ec_dec_init, ec_dec_uint}; +use crate::celt::float_cast::FLOAT2INT16; +use crate::celt::mathops::celt_exp2; +use crate::celt::modes::OpusCustomMode; +use crate::externs::memset; +use crate::silk::dec_API::silk_DecControlStruct; +use crate::silk::dec_API::{silk_Decode, silk_Get_Decoder_Size, silk_InitDecoder}; +use crate::src::opus::opus_packet_parse_impl; +use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_MEDIUMBAND, + OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_WIDEBAND, + OPUS_BUFFER_TOO_SMALL, OPUS_GET_BANDWIDTH_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST, + OPUS_GET_GAIN_REQUEST, OPUS_GET_LAST_PACKET_DURATION_REQUEST, + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PITCH_REQUEST, + OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_INTERNAL_ERROR, OPUS_INVALID_PACKET, OPUS_OK, + OPUS_RESET_STATE, OPUS_SET_GAIN_REQUEST, OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, + OPUS_UNIMPLEMENTED, +}; +use crate::src::opus_private::{align, MODE_CELT_ONLY, MODE_HYBRID, MODE_SILK_ONLY}; +use crate::varargs::VarArgs; +use crate::{opus_custom_decoder_ctl, opus_packet_get_samples_per_frame, opus_pcm_soft_clip}; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusDecoder { + pub(crate) celt_dec_offset: i32, + pub(crate) silk_dec_offset: i32, + pub(crate) channels: i32, + pub(crate) Fs: i32, + pub(crate) DecControl: silk_DecControlStruct, + pub(crate) decode_gain: i32, + pub(crate) arch: i32, + pub(crate) stream_channels: i32, + pub(crate) bandwidth: i32, + pub(crate) mode: i32, + pub(crate) prev_mode: i32, + pub(crate) frame_size: i32, + pub(crate) prev_redundancy: i32, + pub(crate) last_packet_duration: i32, + pub(crate) softclip_mem: [opus_val16; 2], + pub(crate) rangeFinal: u32, +} +unsafe fn validate_opus_decoder(st: *mut OpusDecoder) { + assert!((*st).channels == 1 || (*st).channels == 2); + assert!( + (*st).Fs == 48000 + || (*st).Fs == 24000 + || (*st).Fs == 16000 + || (*st).Fs == 12000 + || (*st).Fs == 8000 + ); + assert!((*st).DecControl.API_sampleRate == (*st).Fs); + assert!( + (*st).DecControl.internalSampleRate == 0 + || (*st).DecControl.internalSampleRate == 16000 + || (*st).DecControl.internalSampleRate == 12000 + || (*st).DecControl.internalSampleRate == 8000 + ); + assert!((*st).DecControl.nChannelsAPI == (*st).channels); + assert!( + (*st).DecControl.nChannelsInternal == 0 + || (*st).DecControl.nChannelsInternal == 1 + || (*st).DecControl.nChannelsInternal == 2 + ); + assert!( + (*st).DecControl.payloadSize_ms == 0 + || (*st).DecControl.payloadSize_ms == 10 + || (*st).DecControl.payloadSize_ms == 20 + || (*st).DecControl.payloadSize_ms == 40 + || (*st).DecControl.payloadSize_ms == 60 + ); + assert!((*st).arch >= 0); + assert!((*st).arch <= 0); + assert!((*st).stream_channels == 1 || (*st).stream_channels == 2); +} +pub unsafe fn opus_decoder_get_size(channels: i32) -> i32 { + let mut silkDecSizeBytes: i32 = 0; + let mut celtDecSizeBytes: i32 = 0; + let mut ret: i32 = 0; + if channels < 1 || channels > 2 { + return 0; + } + ret = silk_Get_Decoder_Size(&mut silkDecSizeBytes); + if ret != 0 { + return 0; + } + silkDecSizeBytes = align(silkDecSizeBytes); + celtDecSizeBytes = celt_decoder_get_size(channels); + return align(::core::mem::size_of::() as u64 as i32) + + silkDecSizeBytes + + celtDecSizeBytes; +} +pub unsafe fn opus_decoder_init(st: *mut OpusDecoder, Fs: i32, channels: i32) -> i32 { + let mut silk_dec: *mut core::ffi::c_void = 0 as *mut core::ffi::c_void; + let mut celt_dec: *mut OpusCustomDecoder = 0 as *mut OpusCustomDecoder; + let mut ret: i32 = 0; + let mut silkDecSizeBytes: i32 = 0; + if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000 + || channels != 1 && channels != 2 + { + return OPUS_BAD_ARG; + } + memset( + st as *mut i8 as *mut core::ffi::c_void, + 0, + (opus_decoder_get_size(channels) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + ret = silk_Get_Decoder_Size(&mut silkDecSizeBytes); + if ret != 0 { + return OPUS_INTERNAL_ERROR; + } + silkDecSizeBytes = align(silkDecSizeBytes); + (*st).silk_dec_offset = align(::core::mem::size_of::() as u64 as i32); + (*st).celt_dec_offset = (*st).silk_dec_offset + silkDecSizeBytes; + silk_dec = (st as *mut i8).offset((*st).silk_dec_offset as isize) as *mut core::ffi::c_void; + celt_dec = (st as *mut i8).offset((*st).celt_dec_offset as isize) as *mut OpusCustomDecoder; + (*st).channels = channels; + (*st).stream_channels = (*st).channels; + (*st).Fs = Fs; + (*st).DecControl.API_sampleRate = (*st).Fs; + (*st).DecControl.nChannelsAPI = (*st).channels; + ret = silk_InitDecoder(silk_dec); + if ret != 0 { + return OPUS_INTERNAL_ERROR; + } + ret = celt_decoder_init(celt_dec, Fs, channels); + if ret != OPUS_OK { + return OPUS_INTERNAL_ERROR; + } + opus_custom_decoder_ctl!(celt_dec, CELT_SET_SIGNALLING_REQUEST, 0); + (*st).prev_mode = 0; + (*st).frame_size = Fs / 400; + (*st).arch = opus_select_arch(); + return OPUS_OK; +} +pub unsafe fn opus_decoder_create(Fs: i32, channels: i32, error: *mut i32) -> *mut OpusDecoder { + let mut ret: i32 = 0; + let mut st: *mut OpusDecoder = 0 as *mut OpusDecoder; + if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000 + || channels != 1 && channels != 2 + { + if !error.is_null() { + *error = OPUS_BAD_ARG; + } + return NULL as *mut OpusDecoder; + } + st = malloc(opus_decoder_get_size(channels) as size_t) as *mut OpusDecoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusDecoder; + } + ret = opus_decoder_init(st, Fs, channels); + if !error.is_null() { + *error = ret; + } + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusDecoder; + } + return st; +} +unsafe fn smooth_fade( + in1: *const opus_val16, + in2: *const opus_val16, + out: *mut opus_val16, + overlap: i32, + channels: i32, + window: *const opus_val16, + Fs: i32, +) { + let mut i: i32 = 0; + let mut c: i32 = 0; + let inc: i32 = 48000 / Fs; + c = 0; + while c < channels { + i = 0; + while i < overlap { + let w: opus_val16 = + *window.offset((i * inc) as isize) * *window.offset((i * inc) as isize); + *out.offset((i * channels + c) as isize) = w * *in2.offset((i * channels + c) as isize) + + (1.0f32 - w) * *in1.offset((i * channels + c) as isize); + i += 1; + } + c += 1; + } +} +unsafe fn opus_packet_get_mode(data: *const u8) -> i32 { + let mut mode: i32 = 0; + if *data.offset(0 as isize) as i32 & 0x80 != 0 { + mode = MODE_CELT_ONLY; + } else if *data.offset(0 as isize) as i32 & 0x60 == 0x60 { + mode = MODE_HYBRID; + } else { + mode = MODE_SILK_ONLY; + } + return mode; +} +unsafe fn opus_decode_frame( + st: *mut OpusDecoder, + mut data: *const u8, + mut len: i32, + mut pcm: *mut opus_val16, + mut frame_size: i32, + decode_fec: i32, +) -> i32 { + let mut silk_dec: *mut core::ffi::c_void = 0 as *mut core::ffi::c_void; + let mut celt_dec: *mut OpusCustomDecoder = 0 as *mut OpusCustomDecoder; + let mut i: i32 = 0; + let mut silk_ret: i32 = 0; + let mut celt_ret: i32 = 0; + let mut dec: ec_dec = ec_dec { + buf: &mut [], + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut silk_frame_size: i32 = 0; + let mut pcm_silk_size: i32 = 0; + let mut pcm_transition_silk_size: i32 = 0; + let mut pcm_transition_celt_size: i32 = 0; + let mut pcm_transition: *mut opus_val16 = NULL as *mut opus_val16; + let mut redundant_audio_size: i32 = 0; + let mut audiosize: i32 = 0; + let mut mode: i32 = 0; + let mut bandwidth: i32 = 0; + let mut transition: i32 = 0; + let mut start_band: i32 = 0; + let mut redundancy: i32 = 0; + let mut redundancy_bytes: i32 = 0; + let mut celt_to_silk: i32 = 0; + let mut c: i32 = 0; + let mut F2_5: i32 = 0; + let mut F5: i32 = 0; + let mut F10: i32 = 0; + let mut F20: i32 = 0; + let mut window: *const opus_val16 = 0 as *const opus_val16; + let mut redundant_rng: u32 = 0; + let mut celt_accum: i32 = 0; + silk_dec = (st as *mut i8).offset((*st).silk_dec_offset as isize) as *mut core::ffi::c_void; + celt_dec = (st as *mut i8).offset((*st).celt_dec_offset as isize) as *mut OpusCustomDecoder; + F20 = (*st).Fs / 50; + F10 = F20 >> 1; + F5 = F10 >> 1; + F2_5 = F5 >> 1; + if frame_size < F2_5 { + return OPUS_BUFFER_TOO_SMALL; + } + frame_size = if frame_size < (*st).Fs / 25 * 3 { + frame_size + } else { + (*st).Fs / 25 * 3 + }; + if len <= 1 { + data = NULL as *const u8; + frame_size = if frame_size < (*st).frame_size { + frame_size + } else { + (*st).frame_size + }; + } + if !data.is_null() { + audiosize = (*st).frame_size; + mode = (*st).mode; + bandwidth = (*st).bandwidth; + dec = ec_dec_init(std::slice::from_raw_parts_mut( + data as *mut u8, + len as usize, + )); + } else { + audiosize = frame_size; + mode = (*st).prev_mode; + bandwidth = 0; + if mode == 0 { + i = 0; + while i < audiosize * (*st).channels { + *pcm.offset(i as isize) = 0 as opus_val16; + i += 1; + } + return audiosize; + } + if audiosize > F20 { + loop { + let ret: i32 = opus_decode_frame( + st, + NULL as *const u8, + 0, + pcm, + if audiosize < F20 { audiosize } else { F20 }, + 0, + ); + if ret < 0 { + return ret; + } + pcm = pcm.offset((ret * (*st).channels) as isize); + audiosize -= ret; + if !(audiosize > 0) { + break; + } + } + return frame_size; + } else { + if audiosize < F20 { + if audiosize > F10 { + audiosize = F10; + } else if mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10 { + audiosize = F5; + } + } + } + } + celt_accum = 0; + pcm_transition_silk_size = ALLOC_NONE; + pcm_transition_celt_size = ALLOC_NONE; + if !data.is_null() + && (*st).prev_mode > 0 + && (mode == MODE_CELT_ONLY + && (*st).prev_mode != MODE_CELT_ONLY + && (*st).prev_redundancy == 0 + || mode != MODE_CELT_ONLY && (*st).prev_mode == MODE_CELT_ONLY) + { + transition = 1; + if mode == MODE_CELT_ONLY { + pcm_transition_celt_size = F5 * (*st).channels; + } else { + pcm_transition_silk_size = F5 * (*st).channels; + } + } + let vla = pcm_transition_celt_size as usize; + let mut pcm_transition_celt: Vec = ::std::vec::from_elem(0., vla); + if transition != 0 && mode == MODE_CELT_ONLY { + pcm_transition = pcm_transition_celt.as_mut_ptr(); + opus_decode_frame( + st, + NULL as *const u8, + 0, + pcm_transition, + if F5 < audiosize { F5 } else { audiosize }, + 0, + ); + } + if audiosize > frame_size { + return OPUS_BAD_ARG; + } else { + frame_size = audiosize; + } + pcm_silk_size = if mode != MODE_CELT_ONLY && celt_accum == 0 { + (if F10 > frame_size { F10 } else { frame_size }) * (*st).channels + } else { + ALLOC_NONE + }; + let vla_0 = pcm_silk_size as usize; + let mut pcm_silk: Vec = ::std::vec::from_elem(0, vla_0); + if mode != MODE_CELT_ONLY { + let mut lost_flag: i32 = 0; + let mut decoded_samples: i32 = 0; + let mut pcm_ptr: *mut i16 = 0 as *mut i16; + pcm_ptr = pcm_silk.as_mut_ptr(); + if (*st).prev_mode == MODE_CELT_ONLY { + silk_InitDecoder(silk_dec); + } + (*st).DecControl.payloadSize_ms = if 10 > 1000 * audiosize / (*st).Fs { + 10 + } else { + 1000 * audiosize / (*st).Fs + }; + if !data.is_null() { + (*st).DecControl.nChannelsInternal = (*st).stream_channels; + if mode == MODE_SILK_ONLY { + if bandwidth == OPUS_BANDWIDTH_NARROWBAND { + (*st).DecControl.internalSampleRate = 8000; + } else if bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + (*st).DecControl.internalSampleRate = 12000; + } else if bandwidth == OPUS_BANDWIDTH_WIDEBAND { + (*st).DecControl.internalSampleRate = 16000; + } else { + (*st).DecControl.internalSampleRate = 16000; + panic!("libopus: assert(0) called"); + } + } else { + (*st).DecControl.internalSampleRate = 16000; + } + } + lost_flag = if data.is_null() { 1 } else { 2 * decode_fec }; + decoded_samples = 0; + loop { + let first_frame: i32 = (decoded_samples == 0) as i32; + silk_ret = silk_Decode( + silk_dec, + &mut (*st).DecControl, + lost_flag, + first_frame, + &mut dec, + pcm_ptr, + &mut silk_frame_size, + (*st).arch, + ); + if silk_ret != 0 { + if lost_flag != 0 { + silk_frame_size = frame_size; + i = 0; + while i < frame_size * (*st).channels { + *pcm_ptr.offset(i as isize) = 0; + i += 1; + } + } else { + return OPUS_INTERNAL_ERROR; + } + } + pcm_ptr = pcm_ptr.offset((silk_frame_size * (*st).channels) as isize); + decoded_samples += silk_frame_size; + if !(decoded_samples < frame_size) { + break; + } + } + } + start_band = 0; + if decode_fec == 0 + && mode != MODE_CELT_ONLY + && !data.is_null() + && ec_tell(&mut dec) + 17 + 20 * ((*st).mode == MODE_HYBRID) as i32 <= 8 * len + { + if mode == MODE_HYBRID { + redundancy = ec_dec_bit_logp(&mut dec, 12); + } else { + redundancy = 1; + } + if redundancy != 0 { + celt_to_silk = ec_dec_bit_logp(&mut dec, 1); + redundancy_bytes = if mode == MODE_HYBRID { + ec_dec_uint(&mut dec, 256) as i32 + 2 + } else { + len - (ec_tell(&mut dec) + 7 >> 3) + }; + len -= redundancy_bytes; + if (len * 8) < ec_tell(&mut dec) { + len = 0; + redundancy_bytes = 0; + redundancy = 0; + } + dec.storage = (dec.storage as u32).wrapping_sub(redundancy_bytes as u32) as u32 as u32; + } + } + if mode != MODE_CELT_ONLY { + start_band = 17; + } + if redundancy != 0 { + transition = 0; + pcm_transition_silk_size = ALLOC_NONE; + } + let vla_1 = pcm_transition_silk_size as usize; + let mut pcm_transition_silk: Vec = ::std::vec::from_elem(0., vla_1); + if transition != 0 && mode != MODE_CELT_ONLY { + pcm_transition = pcm_transition_silk.as_mut_ptr(); + opus_decode_frame( + st, + NULL as *const u8, + 0, + pcm_transition, + if F5 < audiosize { F5 } else { audiosize }, + 0, + ); + } + if bandwidth != 0 { + let mut endband: i32 = 21; + match bandwidth { + OPUS_BANDWIDTH_NARROWBAND => { + endband = 13; + } + OPUS_BANDWIDTH_MEDIUMBAND | OPUS_BANDWIDTH_WIDEBAND => { + endband = 17; + } + OPUS_BANDWIDTH_SUPERWIDEBAND => { + endband = 19; + } + OPUS_BANDWIDTH_FULLBAND => { + endband = 21; + } + _ => { + panic!("libopus: assert(0) called"); + } + } + assert!(opus_custom_decoder_ctl!(celt_dec, 10012, endband) == 0); + } + assert!(opus_custom_decoder_ctl!(celt_dec, 10008, (*st).stream_channels) == 0); + redundant_audio_size = if redundancy != 0 { + F5 * (*st).channels + } else { + ALLOC_NONE + }; + let vla_2 = redundant_audio_size as usize; + let mut redundant_audio: Vec = ::std::vec::from_elem(0., vla_2); + if redundancy != 0 && celt_to_silk != 0 { + assert!(opus_custom_decoder_ctl!(celt_dec, 10010, 0) == 0); + celt_decode_with_ec( + celt_dec, + data.offset(len as isize), + redundancy_bytes, + redundant_audio.as_mut_ptr(), + F5, + None, + 0, + ); + assert!(opus_custom_decoder_ctl!(celt_dec, 4031, &mut redundant_rng) == 0); + } + assert!(opus_custom_decoder_ctl!(celt_dec, 10010, start_band) == 0); + if mode != MODE_SILK_ONLY { + let celt_frame_size: i32 = if F20 < frame_size { F20 } else { frame_size }; + if mode != (*st).prev_mode && (*st).prev_mode > 0 && (*st).prev_redundancy == 0 { + assert!(opus_custom_decoder_ctl!(celt_dec, 4028) == 0); + } + celt_ret = celt_decode_with_ec( + celt_dec, + if decode_fec != 0 { + NULL as *const u8 + } else { + data + }, + len, + pcm, + celt_frame_size, + Some(&mut dec), + celt_accum, + ); + } else { + let mut silence: [u8; 2] = [0xff, 0xff]; + if celt_accum == 0 { + i = 0; + while i < frame_size * (*st).channels { + *pcm.offset(i as isize) = 0 as opus_val16; + i += 1; + } + } + if (*st).prev_mode == MODE_HYBRID + && !(redundancy != 0 && celt_to_silk != 0 && (*st).prev_redundancy != 0) + { + assert!(opus_custom_decoder_ctl!(celt_dec, 10010, 0) == 0); + celt_decode_with_ec( + celt_dec, + silence.as_mut_ptr(), + 2, + pcm, + F2_5, + None, + celt_accum, + ); + } + } + if mode != MODE_CELT_ONLY && celt_accum == 0 { + i = 0; + while i < frame_size * (*st).channels { + *pcm.offset(i as isize) = *pcm.offset(i as isize) + + 1.0f32 / 32768.0f32 * *pcm_silk.as_mut_ptr().offset(i as isize) as i32 as f32; + i += 1; + } + } + let mut celt_mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + assert!(opus_custom_decoder_ctl!(celt_dec, 10015, &mut celt_mode) == 0); + window = (*celt_mode).window; + if redundancy != 0 && celt_to_silk == 0 { + assert!(opus_custom_decoder_ctl!(celt_dec, 4028) == 0); + assert!(opus_custom_decoder_ctl!(celt_dec, 10010, 0) == 0); + celt_decode_with_ec( + celt_dec, + data.offset(len as isize), + redundancy_bytes, + redundant_audio.as_mut_ptr(), + F5, + None, + 0, + ); + assert!(opus_custom_decoder_ctl!(celt_dec, 4031, &mut redundant_rng) == 0); + smooth_fade( + pcm.offset(((*st).channels * (frame_size - F2_5)) as isize), + redundant_audio + .as_mut_ptr() + .offset(((*st).channels * F2_5) as isize), + pcm.offset(((*st).channels * (frame_size - F2_5)) as isize), + F2_5, + (*st).channels, + window, + (*st).Fs, + ); + } + if redundancy != 0 && celt_to_silk != 0 { + c = 0; + while c < (*st).channels { + i = 0; + while i < F2_5 { + *pcm.offset(((*st).channels * i + c) as isize) = *redundant_audio + .as_mut_ptr() + .offset(((*st).channels * i + c) as isize); + i += 1; + } + c += 1; + } + smooth_fade( + redundant_audio + .as_mut_ptr() + .offset(((*st).channels * F2_5) as isize), + pcm.offset(((*st).channels * F2_5) as isize), + pcm.offset(((*st).channels * F2_5) as isize), + F2_5, + (*st).channels, + window, + (*st).Fs, + ); + } + if transition != 0 { + if audiosize >= F5 { + i = 0; + while i < (*st).channels * F2_5 { + *pcm.offset(i as isize) = *pcm_transition.offset(i as isize); + i += 1; + } + smooth_fade( + pcm_transition.offset(((*st).channels * F2_5) as isize), + pcm.offset(((*st).channels * F2_5) as isize), + pcm.offset(((*st).channels * F2_5) as isize), + F2_5, + (*st).channels, + window, + (*st).Fs, + ); + } else { + smooth_fade( + pcm_transition, + pcm, + pcm, + F2_5, + (*st).channels, + window, + (*st).Fs, + ); + } + } + if (*st).decode_gain != 0 { + let mut gain: opus_val32 = 0.; + gain = celt_exp2(6.48814081e-4f32 * (*st).decode_gain as f32); + i = 0; + while i < frame_size * (*st).channels { + let mut x: opus_val32 = 0.; + x = *pcm.offset(i as isize) * gain; + *pcm.offset(i as isize) = x; + i += 1; + } + } + if len <= 1 { + (*st).rangeFinal = 0; + } else { + (*st).rangeFinal = dec.rng ^ redundant_rng; + } + (*st).prev_mode = mode; + (*st).prev_redundancy = (redundancy != 0 && celt_to_silk == 0) as i32; + if celt_ret >= 0 { + let _ = _opus_false() != 0; + } + return if celt_ret < 0 { celt_ret } else { audiosize }; +} +pub unsafe fn opus_decode_native( + st: *mut OpusDecoder, + mut data: *const u8, + len: i32, + pcm: *mut opus_val16, + frame_size: i32, + decode_fec: i32, + self_delimited: i32, + packet_offset: *mut i32, + soft_clip: i32, +) -> i32 { + let mut i: i32 = 0; + let mut nb_samples: i32 = 0; + let mut count: i32 = 0; + let mut offset: i32 = 0; + let mut toc: u8 = 0; + let mut packet_frame_size: i32 = 0; + let mut packet_bandwidth: i32 = 0; + let mut packet_mode: i32 = 0; + let mut packet_stream_channels: i32 = 0; + let mut size: [i16; 48] = [0; 48]; + validate_opus_decoder(st); + if decode_fec < 0 || decode_fec > 1 { + return OPUS_BAD_ARG; + } + if (decode_fec != 0 || len == 0 || data.is_null()) && frame_size % ((*st).Fs / 400) != 0 { + return OPUS_BAD_ARG; + } + if len == 0 || data.is_null() { + let mut pcm_count: i32 = 0; + loop { + let mut ret: i32 = 0; + ret = opus_decode_frame( + st, + NULL as *const u8, + 0, + pcm.offset((pcm_count * (*st).channels) as isize), + frame_size - pcm_count, + 0, + ); + if ret < 0 { + return ret; + } + pcm_count += ret; + if !(pcm_count < frame_size) { + break; + } + } + assert!(pcm_count == frame_size); + let _ = _opus_false() != 0; + (*st).last_packet_duration = pcm_count; + return pcm_count; + } else { + if len < 0 { + return OPUS_BAD_ARG; + } + } + packet_mode = opus_packet_get_mode(data); + packet_bandwidth = opus_packet_get_bandwidth(data); + packet_frame_size = opus_packet_get_samples_per_frame(data, (*st).Fs); + packet_stream_channels = opus_packet_get_nb_channels(data); + count = opus_packet_parse_impl( + data, + len, + self_delimited, + &mut toc, + NULL as *mut *const u8, + size.as_mut_ptr(), + &mut offset, + packet_offset, + ); + if count < 0 { + return count; + } + data = data.offset(offset as isize); + if decode_fec != 0 { + let mut duration_copy: i32 = 0; + let mut ret_0: i32 = 0; + if frame_size < packet_frame_size + || packet_mode == MODE_CELT_ONLY + || (*st).mode == MODE_CELT_ONLY + { + return opus_decode_native( + st, + NULL as *const u8, + 0, + pcm, + frame_size, + 0, + 0, + NULL as *mut i32, + soft_clip, + ); + } + duration_copy = (*st).last_packet_duration; + if frame_size - packet_frame_size != 0 { + ret_0 = opus_decode_native( + st, + NULL as *const u8, + 0, + pcm, + frame_size - packet_frame_size, + 0, + 0, + NULL as *mut i32, + soft_clip, + ); + if ret_0 < 0 { + (*st).last_packet_duration = duration_copy; + return ret_0; + } + assert!(ret_0 == frame_size - packet_frame_size); + } + (*st).mode = packet_mode; + (*st).bandwidth = packet_bandwidth; + (*st).frame_size = packet_frame_size; + (*st).stream_channels = packet_stream_channels; + ret_0 = opus_decode_frame( + st, + data, + size[0 as usize] as i32, + pcm.offset(((*st).channels * (frame_size - packet_frame_size)) as isize), + packet_frame_size, + 1, + ); + if ret_0 < 0 { + return ret_0; + } else { + let _ = _opus_false() != 0; + (*st).last_packet_duration = frame_size; + return frame_size; + } + } + if count * packet_frame_size > frame_size { + return OPUS_BUFFER_TOO_SMALL; + } + (*st).mode = packet_mode; + (*st).bandwidth = packet_bandwidth; + (*st).frame_size = packet_frame_size; + (*st).stream_channels = packet_stream_channels; + nb_samples = 0; + i = 0; + while i < count { + let mut ret_1: i32 = 0; + ret_1 = opus_decode_frame( + st, + data, + size[i as usize] as i32, + pcm.offset((nb_samples * (*st).channels) as isize), + frame_size - nb_samples, + 0, + ); + if ret_1 < 0 { + return ret_1; + } + assert!(ret_1 == packet_frame_size); + data = data.offset(size[i as usize] as i32 as isize); + nb_samples += ret_1; + i += 1; + } + (*st).last_packet_duration = nb_samples; + let _ = _opus_false() != 0; + if soft_clip != 0 { + opus_pcm_soft_clip( + pcm, + nb_samples, + (*st).channels, + ((*st).softclip_mem).as_mut_ptr(), + ); + } else { + (*st).softclip_mem[1 as usize] = 0 as opus_val16; + (*st).softclip_mem[0 as usize] = (*st).softclip_mem[1 as usize]; + } + return nb_samples; +} +pub unsafe fn opus_decode( + st: *mut OpusDecoder, + data: *const u8, + len: i32, + pcm: *mut i16, + mut frame_size: i32, + decode_fec: i32, +) -> i32 { + let mut ret: i32 = 0; + let mut i: i32 = 0; + let mut nb_samples: i32 = 0; + if frame_size <= 0 { + return OPUS_BAD_ARG; + } + if !data.is_null() && len > 0 && decode_fec == 0 { + nb_samples = opus_decoder_get_nb_samples(st, data, len); + if nb_samples > 0 { + frame_size = if frame_size < nb_samples { + frame_size + } else { + nb_samples + }; + } else { + return OPUS_INVALID_PACKET; + } + } + assert!((*st).channels == 1 || (*st).channels == 2); + let vla = (frame_size * (*st).channels) as usize; + let mut out: Vec = ::std::vec::from_elem(0., vla); + ret = opus_decode_native( + st, + data, + len, + out.as_mut_ptr(), + frame_size, + decode_fec, + 0, + NULL as *mut i32, + 1, + ); + if ret > 0 { + i = 0; + while i < ret * (*st).channels { + *pcm.offset(i as isize) = FLOAT2INT16(*out.as_mut_ptr().offset(i as isize)); + i += 1; + } + } + return ret; +} +pub unsafe fn opus_decode_float( + st: *mut OpusDecoder, + data: *const u8, + len: i32, + pcm: *mut opus_val16, + frame_size: i32, + decode_fec: i32, +) -> i32 { + if frame_size <= 0 { + return OPUS_BAD_ARG; + } + return opus_decode_native( + st, + data, + len, + pcm, + frame_size, + decode_fec, + 0, + NULL as *mut i32, + 0, + ); +} +pub unsafe fn opus_decoder_ctl_impl(st: *mut OpusDecoder, request: i32, args: VarArgs) -> i32 { + let mut silk_dec: *mut core::ffi::c_void = 0 as *mut core::ffi::c_void; + let mut celt_dec: *mut OpusCustomDecoder = 0 as *mut OpusCustomDecoder; + silk_dec = (st as *mut i8).offset((*st).silk_dec_offset as isize) as *mut core::ffi::c_void; + celt_dec = (st as *mut i8).offset((*st).celt_dec_offset as isize) as *mut OpusCustomDecoder; + + let mut ap = args; + + match request { + OPUS_GET_BANDWIDTH_REQUEST => { + let value = ap.arg::<&mut i32>(); + *value = (*st).bandwidth; + OPUS_OK + } + OPUS_GET_FINAL_RANGE_REQUEST => { + let value_0 = ap.arg::<&mut u32>(); + *value_0 = (*st).rangeFinal; + OPUS_OK + } + OPUS_RESET_STATE => { + memset( + &mut (*st).stream_channels as *mut i32 as *mut i8 as *mut core::ffi::c_void, + 0, + (::core::mem::size_of::() as u64) + .wrapping_sub( + (&mut (*st).stream_channels as *mut i32 as *mut i8) + .offset_from(st as *mut i8) as i64 as u64, + ) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + opus_custom_decoder_ctl!(celt_dec, OPUS_RESET_STATE); + silk_InitDecoder(silk_dec); + (*st).stream_channels = (*st).channels; + (*st).frame_size = (*st).Fs / 400; + OPUS_OK + } + OPUS_GET_SAMPLE_RATE_REQUEST => { + let value_1 = ap.arg::<&mut i32>(); + *value_1 = (*st).Fs; + OPUS_OK + } + OPUS_GET_PITCH_REQUEST => { + let value_2 = ap.arg::<&mut i32>(); + if (*st).prev_mode == MODE_CELT_ONLY { + opus_custom_decoder_ctl!(celt_dec, OPUS_GET_PITCH_REQUEST, value_2,) + } else { + *value_2 = (*st).DecControl.prevPitchLag; + OPUS_OK + } + } + OPUS_GET_GAIN_REQUEST => { + let value_3 = ap.arg::<&mut i32>(); + *value_3 = (*st).decode_gain; + OPUS_OK + } + OPUS_SET_GAIN_REQUEST => { + let value_4: i32 = ap.arg::(); + if value_4 < -(32768) || value_4 > 32767 { + OPUS_BAD_ARG + } else { + (*st).decode_gain = value_4; + OPUS_OK + } + } + OPUS_GET_LAST_PACKET_DURATION_REQUEST => { + let value_5 = ap.arg::<&mut i32>(); + *value_5 = (*st).last_packet_duration; + OPUS_OK + } + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_6: i32 = ap.arg::(); + if value_6 < 0 || value_6 > 1 { + OPUS_BAD_ARG + } else { + opus_custom_decoder_ctl!( + celt_dec, + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, + value_6 + ) + } + } + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_7 = ap.arg::<&mut i32>(); + opus_custom_decoder_ctl!(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, value_7) + } + _ => OPUS_UNIMPLEMENTED, + } +} +#[macro_export] +macro_rules! opus_decoder_ctl { + ($st:expr,$request:expr, $($arg:expr),*) => { + $crate::opus_decoder_ctl_impl( + $st, + $request, + $crate::varargs!($($arg),*) + ) + }; + ($st:expr,$request:expr, $($arg:expr),*,) => { + opus_decoder_ctl!($st, $request, $($arg),*) + }; + ($st:expr,$request:expr) => { + opus_decoder_ctl!($st, $request,) + }; +} +pub unsafe fn opus_decoder_destroy(st: *mut OpusDecoder) { + free(st as *mut core::ffi::c_void); +} +pub unsafe fn opus_packet_get_bandwidth(data: *const u8) -> i32 { + let mut bandwidth: i32 = 0; + if *data.offset(0 as isize) as i32 & 0x80 != 0 { + bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + (*data.offset(0 as isize) as i32 >> 5 & 0x3); + if bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } + } else if *data.offset(0 as isize) as i32 & 0x60 == 0x60 { + bandwidth = if *data.offset(0 as isize) as i32 & 0x10 != 0 { + OPUS_BANDWIDTH_FULLBAND + } else { + OPUS_BANDWIDTH_SUPERWIDEBAND + }; + } else { + bandwidth = OPUS_BANDWIDTH_NARROWBAND + (*data.offset(0 as isize) as i32 >> 5 & 0x3); + } + return bandwidth; +} +pub unsafe fn opus_packet_get_nb_channels(data: *const u8) -> i32 { + return if *data.offset(0 as isize) as i32 & 0x4 != 0 { + 2 + } else { + 1 + }; +} +pub unsafe fn opus_packet_get_nb_frames(packet: *const u8, len: i32) -> i32 { + let mut count: i32 = 0; + if len < 1 { + return OPUS_BAD_ARG; + } + count = *packet.offset(0 as isize) as i32 & 0x3; + if count == 0 { + return 1; + } else if count != 3 { + return 2; + } else if len < 2 { + return OPUS_INVALID_PACKET; + } else { + return *packet.offset(1 as isize) as i32 & 0x3f; + }; +} +pub unsafe fn opus_packet_get_nb_samples(packet: *const u8, len: i32, Fs: i32) -> i32 { + let mut samples: i32 = 0; + let count: i32 = opus_packet_get_nb_frames(packet, len); + if count < 0 { + return count; + } + samples = count * opus_packet_get_samples_per_frame(packet, Fs); + if samples * 25 > Fs * 3 { + return OPUS_INVALID_PACKET; + } else { + return samples; + }; +} +pub unsafe fn opus_decoder_get_nb_samples( + dec: *const OpusDecoder, + packet: *const u8, + len: i32, +) -> i32 { + return opus_packet_get_nb_samples(packet, len, (*dec).Fs); +} diff --git a/vendor/unsafe-libopus/src/src/opus_defines.rs b/vendor/unsafe-libopus/src/src/opus_defines.rs new file mode 100644 index 00000000..941b2c5e --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_defines.rs @@ -0,0 +1,76 @@ +pub const OPUS_OK: i32 = 0; +pub const OPUS_BAD_ARG: i32 = -1; +pub const OPUS_BUFFER_TOO_SMALL: i32 = -2; +pub const OPUS_INTERNAL_ERROR: i32 = -3; +pub const OPUS_INVALID_PACKET: i32 = -4; +pub const OPUS_UNIMPLEMENTED: i32 = -5; +pub const OPUS_INVALID_STATE: i32 = -6; +pub const OPUS_ALLOC_FAIL: i32 = -7; + +pub const OPUS_SET_APPLICATION_REQUEST: i32 = 4000; +pub const OPUS_GET_APPLICATION_REQUEST: i32 = 4001; +pub const OPUS_SET_BITRATE_REQUEST: i32 = 4002; +pub const OPUS_GET_BITRATE_REQUEST: i32 = 4003; +pub const OPUS_SET_MAX_BANDWIDTH_REQUEST: i32 = 4004; +pub const OPUS_GET_MAX_BANDWIDTH_REQUEST: i32 = 4005; +pub const OPUS_SET_VBR_REQUEST: i32 = 4006; +pub const OPUS_GET_VBR_REQUEST: i32 = 4007; +pub const OPUS_SET_BANDWIDTH_REQUEST: i32 = 4008; +pub const OPUS_GET_BANDWIDTH_REQUEST: i32 = 4009; +pub const OPUS_SET_COMPLEXITY_REQUEST: i32 = 4010; +pub const OPUS_GET_COMPLEXITY_REQUEST: i32 = 4011; +pub const OPUS_SET_INBAND_FEC_REQUEST: i32 = 4012; +pub const OPUS_GET_INBAND_FEC_REQUEST: i32 = 4013; +pub const OPUS_SET_PACKET_LOSS_PERC_REQUEST: i32 = 4014; +pub const OPUS_GET_PACKET_LOSS_PERC_REQUEST: i32 = 4015; +pub const OPUS_SET_DTX_REQUEST: i32 = 4016; +pub const OPUS_GET_DTX_REQUEST: i32 = 4017; +pub const OPUS_SET_VBR_CONSTRAINT_REQUEST: i32 = 4020; +pub const OPUS_GET_VBR_CONSTRAINT_REQUEST: i32 = 4021; +pub const OPUS_SET_FORCE_CHANNELS_REQUEST: i32 = 4022; +pub const OPUS_GET_FORCE_CHANNELS_REQUEST: i32 = 4023; +pub const OPUS_SET_SIGNAL_REQUEST: i32 = 4024; +pub const OPUS_GET_SIGNAL_REQUEST: i32 = 4025; +pub const OPUS_GET_LOOKAHEAD_REQUEST: i32 = 4027; +pub const OPUS_RESET_STATE: i32 = 4028; +pub const OPUS_GET_SAMPLE_RATE_REQUEST: i32 = 4029; +pub const OPUS_GET_FINAL_RANGE_REQUEST: i32 = 4031; +pub const OPUS_GET_PITCH_REQUEST: i32 = 4033; +pub const OPUS_SET_GAIN_REQUEST: i32 = 4034; +pub const OPUS_GET_GAIN_REQUEST: i32 = 4045; /* Should have been 4035 */ +pub const OPUS_SET_LSB_DEPTH_REQUEST: i32 = 4036; +pub const OPUS_GET_LSB_DEPTH_REQUEST: i32 = 4037; +pub const OPUS_GET_LAST_PACKET_DURATION_REQUEST: i32 = 4039; +pub const OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: i32 = 4040; +pub const OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: i32 = 4041; +pub const OPUS_SET_PREDICTION_DISABLED_REQUEST: i32 = 4042; +pub const OPUS_GET_PREDICTION_DISABLED_REQUEST: i32 = 4043; +pub const OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: i32 = 4046; +pub const OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: i32 = 4047; +pub const OPUS_GET_IN_DTX_REQUEST: i32 = 4049; + +pub const OPUS_AUTO: i32 = -1000; +pub const OPUS_BITRATE_MAX: i32 = -1; + +pub const OPUS_APPLICATION_VOIP: i32 = 2048; +pub const OPUS_APPLICATION_AUDIO: i32 = 2049; +pub const OPUS_APPLICATION_RESTRICTED_LOWDELAY: i32 = 2051; + +pub const OPUS_SIGNAL_VOICE: i32 = 3001; +pub const OPUS_SIGNAL_MUSIC: i32 = 3002; +pub const OPUS_BANDWIDTH_NARROWBAND: i32 = 1101; +pub const OPUS_BANDWIDTH_MEDIUMBAND: i32 = 1102; +pub const OPUS_BANDWIDTH_WIDEBAND: i32 = 1103; +pub const OPUS_BANDWIDTH_SUPERWIDEBAND: i32 = 1104; +pub const OPUS_BANDWIDTH_FULLBAND: i32 = 1105; + +pub const OPUS_FRAMESIZE_ARG: i32 = 5000; +pub const OPUS_FRAMESIZE_2_5_MS: i32 = 5001; +pub const OPUS_FRAMESIZE_5_MS: i32 = 5002; +pub const OPUS_FRAMESIZE_10_MS: i32 = 5003; +pub const OPUS_FRAMESIZE_20_MS: i32 = 5004; +pub const OPUS_FRAMESIZE_40_MS: i32 = 5005; +pub const OPUS_FRAMESIZE_60_MS: i32 = 5006; +pub const OPUS_FRAMESIZE_80_MS: i32 = 5007; +pub const OPUS_FRAMESIZE_100_MS: i32 = 5008; +pub const OPUS_FRAMESIZE_120_MS: i32 = 5009; diff --git a/vendor/unsafe-libopus/src/src/opus_encoder.rs b/vendor/unsafe-libopus/src/src/opus_encoder.rs new file mode 100644 index 00000000..02afd508 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_encoder.rs @@ -0,0 +1,3034 @@ +use crate::externs::{free, malloc}; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; + pub const CELT_SIG_SCALE: f32 = 32768.0f32; + pub const Q15ONE: f32 = 1.0f32; + pub const EPSILON: f32 = 1e-15f32; + pub const VERY_SMALL: f32 = 1e-30f32; +} +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +use self::arch_h::{opus_val16, opus_val32, CELT_SIG_SCALE, EPSILON, Q15ONE, VERY_SMALL}; +pub use self::cpu_support_h::opus_select_arch; +pub use self::stddef_h::{size_t, NULL}; +use crate::celt::celt::{ + CELT_GET_MODE_REQUEST, CELT_SET_ANALYSIS_REQUEST, CELT_SET_CHANNELS_REQUEST, + CELT_SET_END_BAND_REQUEST, CELT_SET_PREDICTION_REQUEST, CELT_SET_SIGNALLING_REQUEST, + CELT_SET_SILK_INFO_REQUEST, CELT_SET_START_BAND_REQUEST, OPUS_SET_ENERGY_MASK_REQUEST, + OPUS_SET_LFE_REQUEST, +}; +use crate::celt::celt_encoder::{ + celt_encode_with_ec, celt_encoder_get_size, celt_encoder_init, OpusCustomEncoder, SILKInfo, +}; +use crate::celt::entcode::ec_tell; +use crate::celt::entenc::ec_enc; +use crate::celt::entenc::{ec_enc_bit_logp, ec_enc_done, ec_enc_init, ec_enc_shrink, ec_enc_uint}; +use crate::celt::float_cast::FLOAT2INT16; +use crate::celt::mathops::{celt_exp2, celt_maxabs16, celt_sqrt}; +use crate::celt::modes::OpusCustomMode; +use crate::celt::pitch::celt_inner_prod_c; +use crate::externs::{memcpy, memmove, memset}; +use crate::silk::define::{ + DTX_ACTIVITY_THRESHOLD, MAX_CONSECUTIVE_DTX, NB_SPEECH_FRAMES_BEFORE_DTX, VAD_NO_DECISION, +}; +use crate::silk::enc_API::silk_EncControlStruct; +use crate::silk::enc_API::{silk_Encode, silk_Get_Encoder_Size, silk_InitEncoder}; +use crate::silk::float::structs_FLP::silk_encoder; +use crate::silk::lin2log::silk_lin2log; +use crate::silk::log2lin::silk_log2lin; +use crate::src::analysis::{ + downmix_func, run_analysis, tonality_analysis_init, tonality_analysis_reset, AnalysisInfo, + TonalityAnalysisState, +}; +use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_RESTRICTED_LOWDELAY, + OPUS_APPLICATION_VOIP, OPUS_AUTO, OPUS_BAD_ARG, OPUS_BANDWIDTH_FULLBAND, + OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_SUPERWIDEBAND, + OPUS_BANDWIDTH_WIDEBAND, OPUS_BITRATE_MAX, OPUS_BUFFER_TOO_SMALL, OPUS_FRAMESIZE_100_MS, + OPUS_FRAMESIZE_10_MS, OPUS_FRAMESIZE_120_MS, OPUS_FRAMESIZE_20_MS, OPUS_FRAMESIZE_2_5_MS, + OPUS_FRAMESIZE_40_MS, OPUS_FRAMESIZE_5_MS, OPUS_FRAMESIZE_60_MS, OPUS_FRAMESIZE_80_MS, + OPUS_FRAMESIZE_ARG, OPUS_GET_APPLICATION_REQUEST, OPUS_GET_BANDWIDTH_REQUEST, + OPUS_GET_BITRATE_REQUEST, OPUS_GET_COMPLEXITY_REQUEST, OPUS_GET_DTX_REQUEST, + OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST, + OPUS_GET_FORCE_CHANNELS_REQUEST, OPUS_GET_INBAND_FEC_REQUEST, OPUS_GET_IN_DTX_REQUEST, + OPUS_GET_LOOKAHEAD_REQUEST, OPUS_GET_LSB_DEPTH_REQUEST, OPUS_GET_MAX_BANDWIDTH_REQUEST, + OPUS_GET_PACKET_LOSS_PERC_REQUEST, OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, + OPUS_GET_PREDICTION_DISABLED_REQUEST, OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_GET_SIGNAL_REQUEST, + OPUS_GET_VBR_CONSTRAINT_REQUEST, OPUS_GET_VBR_REQUEST, OPUS_INTERNAL_ERROR, OPUS_OK, + OPUS_RESET_STATE, OPUS_SET_APPLICATION_REQUEST, OPUS_SET_BANDWIDTH_REQUEST, + OPUS_SET_BITRATE_REQUEST, OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST, + OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, OPUS_SET_FORCE_CHANNELS_REQUEST, + OPUS_SET_INBAND_FEC_REQUEST, OPUS_SET_LSB_DEPTH_REQUEST, OPUS_SET_MAX_BANDWIDTH_REQUEST, + OPUS_SET_PACKET_LOSS_PERC_REQUEST, OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, + OPUS_SET_PREDICTION_DISABLED_REQUEST, OPUS_SET_SIGNAL_REQUEST, OPUS_SET_VBR_CONSTRAINT_REQUEST, + OPUS_SET_VBR_REQUEST, OPUS_SIGNAL_MUSIC, OPUS_SIGNAL_VOICE, OPUS_UNIMPLEMENTED, +}; +use crate::src::opus_private::{ + align, MODE_CELT_ONLY, MODE_HYBRID, MODE_SILK_ONLY, OPUS_GET_VOICE_RATIO_REQUEST, + OPUS_SET_FORCE_MODE_REQUEST, OPUS_SET_VOICE_RATIO_REQUEST, +}; +use crate::varargs::VarArgs; +use crate::{ + opus_custom_encoder_ctl, opus_packet_pad, opus_repacketizer_cat, opus_repacketizer_init, + opus_repacketizer_out_range_impl, OpusRepacketizer, +}; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusEncoder { + pub(crate) celt_enc_offset: i32, + pub(crate) silk_enc_offset: i32, + pub(crate) silk_mode: silk_EncControlStruct, + pub(crate) application: i32, + pub(crate) channels: i32, + pub(crate) delay_compensation: i32, + pub(crate) force_channels: i32, + pub(crate) signal_type: i32, + pub(crate) user_bandwidth: i32, + pub(crate) max_bandwidth: i32, + pub(crate) user_forced_mode: i32, + pub(crate) voice_ratio: i32, + pub(crate) Fs: i32, + pub(crate) use_vbr: i32, + pub(crate) vbr_constraint: i32, + pub(crate) variable_duration: i32, + pub(crate) bitrate_bps: i32, + pub(crate) user_bitrate_bps: i32, + pub(crate) lsb_depth: i32, + pub(crate) encoder_buffer: i32, + pub(crate) lfe: i32, + pub(crate) arch: i32, + pub(crate) use_dtx: i32, + pub(crate) analysis: TonalityAnalysisState, + pub(crate) stream_channels: i32, + pub(crate) hybrid_stereo_width_Q14: i16, + pub(crate) variable_HP_smth2_Q15: i32, + pub(crate) prev_HB_gain: opus_val16, + pub(crate) hp_mem: [opus_val32; 4], + pub(crate) mode: i32, + pub(crate) prev_mode: i32, + pub(crate) prev_channels: i32, + pub(crate) prev_framesize: i32, + pub(crate) bandwidth: i32, + pub(crate) auto_bandwidth: i32, + pub(crate) silk_bw_switch: i32, + pub(crate) first: i32, + pub(crate) energy_masking: *mut opus_val16, + pub(crate) width_mem: StereoWidthState, + pub(crate) delay_buffer: [opus_val16; 960], + pub(crate) detected_bandwidth: i32, + pub(crate) nb_no_activity_frames: i32, + pub(crate) peak_signal_energy: opus_val32, + pub(crate) nonfinal_frame: i32, + pub(crate) rangeFinal: u32, +} +#[derive(Copy, Clone)] +#[repr(C)] +pub struct StereoWidthState { + pub XX: opus_val32, + pub XY: opus_val32, + pub YY: opus_val32, + pub smoothed_width: opus_val16, + pub max_follower: opus_val16, +} +pub const PSEUDO_SNR_THRESHOLD: f32 = 316.23f32; +static mut mono_voice_bandwidth_thresholds: [i32; 8] = + [9000, 700, 9000, 700, 13500, 1000, 14000, 2000]; +static mut mono_music_bandwidth_thresholds: [i32; 8] = + [9000, 700, 9000, 700, 11000, 1000, 12000, 2000]; +static mut stereo_voice_bandwidth_thresholds: [i32; 8] = + [9000, 700, 9000, 700, 13500, 1000, 14000, 2000]; +static mut stereo_music_bandwidth_thresholds: [i32; 8] = + [9000, 700, 9000, 700, 11000, 1000, 12000, 2000]; +static mut stereo_voice_threshold: i32 = 19000; +static mut stereo_music_threshold: i32 = 17000; +static mut mode_thresholds: [[i32; 2]; 2] = [[64000, 10000], [44000, 10000]]; +static mut fec_thresholds: [i32; 10] = [ + 12000, 1000, 14000, 1000, 16000, 1000, 20000, 1000, 22000, 1000, +]; +pub unsafe fn opus_encoder_get_size(channels: i32) -> i32 { + let mut silkEncSizeBytes: i32 = 0; + let mut celtEncSizeBytes: i32 = 0; + let mut ret: i32 = 0; + if channels < 1 || channels > 2 { + return 0; + } + ret = silk_Get_Encoder_Size(&mut silkEncSizeBytes); + if ret != 0 { + return 0; + } + silkEncSizeBytes = align(silkEncSizeBytes); + celtEncSizeBytes = celt_encoder_get_size(channels); + return align(::core::mem::size_of::() as u64 as i32) + + silkEncSizeBytes + + celtEncSizeBytes; +} +pub unsafe fn opus_encoder_init( + st: *mut OpusEncoder, + Fs: i32, + channels: i32, + application: i32, +) -> i32 { + let mut silk_enc: *mut core::ffi::c_void = 0 as *mut core::ffi::c_void; + let mut celt_enc: *mut OpusCustomEncoder = 0 as *mut OpusCustomEncoder; + let mut err: i32 = 0; + let mut ret: i32 = 0; + let mut silkEncSizeBytes: i32 = 0; + if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000 + || channels != 1 && channels != 2 + || application != OPUS_APPLICATION_VOIP + && application != OPUS_APPLICATION_AUDIO + && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY + { + return OPUS_BAD_ARG; + } + memset( + st as *mut i8 as *mut core::ffi::c_void, + 0, + (opus_encoder_get_size(channels) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + ret = silk_Get_Encoder_Size(&mut silkEncSizeBytes); + if ret != 0 { + return OPUS_BAD_ARG; + } + silkEncSizeBytes = align(silkEncSizeBytes); + (*st).silk_enc_offset = align(::core::mem::size_of::() as u64 as i32); + (*st).celt_enc_offset = (*st).silk_enc_offset + silkEncSizeBytes; + silk_enc = (st as *mut i8).offset((*st).silk_enc_offset as isize) as *mut core::ffi::c_void; + celt_enc = (st as *mut i8).offset((*st).celt_enc_offset as isize) as *mut OpusCustomEncoder; + (*st).channels = channels; + (*st).stream_channels = (*st).channels; + (*st).Fs = Fs; + (*st).arch = opus_select_arch(); + ret = silk_InitEncoder(silk_enc, (*st).arch, &mut (*st).silk_mode); + if ret != 0 { + return OPUS_INTERNAL_ERROR; + } + (*st).silk_mode.nChannelsAPI = channels; + (*st).silk_mode.nChannelsInternal = channels; + (*st).silk_mode.API_sampleRate = (*st).Fs; + (*st).silk_mode.maxInternalSampleRate = 16000; + (*st).silk_mode.minInternalSampleRate = 8000; + (*st).silk_mode.desiredInternalSampleRate = 16000; + (*st).silk_mode.payloadSize_ms = 20; + (*st).silk_mode.bitRate = 25000; + (*st).silk_mode.packetLossPercentage = 0; + (*st).silk_mode.complexity = 9; + (*st).silk_mode.useInBandFEC = 0; + (*st).silk_mode.useDTX = 0; + (*st).silk_mode.useCBR = 0; + (*st).silk_mode.reducedDependency = 0; + err = celt_encoder_init(celt_enc, Fs, channels, (*st).arch); + if err != OPUS_OK { + return OPUS_INTERNAL_ERROR; + } + opus_custom_encoder_ctl!(celt_enc, CELT_SET_SIGNALLING_REQUEST, 0); + opus_custom_encoder_ctl!( + celt_enc, + OPUS_SET_COMPLEXITY_REQUEST, + (*st).silk_mode.complexity, + ); + (*st).use_vbr = 1; + (*st).vbr_constraint = 1; + (*st).user_bitrate_bps = OPUS_AUTO; + (*st).bitrate_bps = 3000 + Fs * channels; + (*st).application = application; + (*st).signal_type = OPUS_AUTO; + (*st).user_bandwidth = OPUS_AUTO; + (*st).max_bandwidth = OPUS_BANDWIDTH_FULLBAND; + (*st).force_channels = OPUS_AUTO; + (*st).user_forced_mode = OPUS_AUTO; + (*st).voice_ratio = -1; + (*st).encoder_buffer = (*st).Fs / 100; + (*st).lsb_depth = 24; + (*st).variable_duration = OPUS_FRAMESIZE_ARG; + (*st).delay_compensation = (*st).Fs / 250; + (*st).hybrid_stereo_width_Q14 = ((1) << 14) as i16; + (*st).prev_HB_gain = Q15ONE; + (*st).variable_HP_smth2_Q15 = ((silk_lin2log(60) as u32) << 8) as i32; + (*st).first = 1; + (*st).mode = MODE_HYBRID; + (*st).bandwidth = OPUS_BANDWIDTH_FULLBAND; + tonality_analysis_init(&mut (*st).analysis, (*st).Fs); + (*st).analysis.application = (*st).application; + return OPUS_OK; +} +unsafe fn gen_toc(mode: i32, mut framerate: i32, bandwidth: i32, channels: i32) -> u8 { + let mut period: i32 = 0; + let mut toc: u8 = 0; + period = 0; + while framerate < 400 { + framerate <<= 1; + period += 1; + } + if mode == MODE_SILK_ONLY { + toc = (bandwidth - OPUS_BANDWIDTH_NARROWBAND << 5) as u8; + toc = (toc as i32 | (period - 2) << 3) as u8; + } else if mode == MODE_CELT_ONLY { + let mut tmp: i32 = bandwidth - OPUS_BANDWIDTH_MEDIUMBAND; + if tmp < 0 { + tmp = 0; + } + toc = 0x80; + toc = (toc as i32 | tmp << 5) as u8; + toc = (toc as i32 | period << 3) as u8; + } else { + toc = 0x60; + toc = (toc as i32 | bandwidth - OPUS_BANDWIDTH_SUPERWIDEBAND << 4) as u8; + toc = (toc as i32 | (period - 2) << 3) as u8; + } + toc = (toc as i32 | ((channels == 2) as i32) << 2) as u8; + return toc; +} +unsafe fn silk_biquad_float( + in_0: *const opus_val16, + B_Q28: *const i32, + A_Q28: *const i32, + S: *mut opus_val32, + out: *mut opus_val16, + len: i32, + stride: i32, +) { + let mut k: i32 = 0; + let mut vout: opus_val32 = 0.; + let mut inval: opus_val32 = 0.; + let mut A: [opus_val32; 2] = [0.; 2]; + let mut B: [opus_val32; 3] = [0.; 3]; + A[0 as usize] = *A_Q28.offset(0 as isize) as f32 * (1.0f32 / ((1) << 28) as f32); + A[1 as usize] = *A_Q28.offset(1 as isize) as f32 * (1.0f32 / ((1) << 28) as f32); + B[0 as usize] = *B_Q28.offset(0 as isize) as f32 * (1.0f32 / ((1) << 28) as f32); + B[1 as usize] = *B_Q28.offset(1 as isize) as f32 * (1.0f32 / ((1) << 28) as f32); + B[2 as usize] = *B_Q28.offset(2 as isize) as f32 * (1.0f32 / ((1) << 28) as f32); + k = 0; + while k < len { + inval = *in_0.offset((k * stride) as isize); + vout = *S.offset(0 as isize) + B[0 as usize] * inval; + *S.offset(0 as isize) = + *S.offset(1 as isize) - vout * A[0 as usize] + B[1 as usize] * inval; + *S.offset(1 as isize) = -vout * A[1 as usize] + B[2 as usize] * inval + VERY_SMALL; + *out.offset((k * stride) as isize) = vout; + k += 1; + } +} +unsafe fn hp_cutoff( + in_0: *const opus_val16, + cutoff_Hz: i32, + out: *mut opus_val16, + hp_mem: *mut opus_val32, + len: i32, + channels: i32, + Fs: i32, + _arch: i32, +) { + let mut B_Q28: [i32; 3] = [0; 3]; + let mut A_Q28: [i32; 2] = [0; 2]; + let mut Fc_Q19: i32 = 0; + let mut r_Q28: i32 = 0; + let mut r_Q22: i32 = 0; + Fc_Q19 = (1.5f64 * 3.14159f64 / 1000 as f64 * ((1) << 19) as f64 + 0.5f64) as i32 as i16 as i32 + * cutoff_Hz as i16 as i32 + / (Fs / 1000); + r_Q28 = (1.0f64 * ((1) << 28) as f64 + 0.5f64) as i32 + - (0.92f64 * ((1) << 9) as f64 + 0.5f64) as i32 * Fc_Q19; + B_Q28[0 as usize] = r_Q28; + B_Q28[1 as usize] = ((-r_Q28 as u32) << 1) as i32; + B_Q28[2 as usize] = r_Q28; + r_Q22 = r_Q28 >> 6; + A_Q28[0 as usize] = (r_Q22 as i64 + * ((Fc_Q19 as i64 * Fc_Q19 as i64 >> 16) as i32 + - (2.0f64 * ((1) << 22) as f64 + 0.5f64) as i32) as i64 + >> 16) as i32; + A_Q28[1 as usize] = (r_Q22 as i64 * r_Q22 as i64 >> 16) as i32; + silk_biquad_float( + in_0, + B_Q28.as_mut_ptr(), + A_Q28.as_mut_ptr(), + hp_mem, + out, + len, + channels, + ); + if channels == 2 { + silk_biquad_float( + in_0.offset(1 as isize), + B_Q28.as_mut_ptr(), + A_Q28.as_mut_ptr(), + hp_mem.offset(2 as isize), + out.offset(1 as isize), + len, + channels, + ); + } +} +unsafe fn dc_reject( + in_0: *const opus_val16, + cutoff_Hz: i32, + out: *mut opus_val16, + hp_mem: *mut opus_val32, + len: i32, + channels: i32, + Fs: i32, +) { + let mut i: i32 = 0; + let mut coef: f32 = 0.; + let mut coef2: f32 = 0.; + coef = 6.3f32 * cutoff_Hz as f32 / Fs as f32; + coef2 = 1 as f32 - coef; + if channels == 2 { + let mut m0: f32 = 0.; + let mut m2: f32 = 0.; + m0 = *hp_mem.offset(0 as isize); + m2 = *hp_mem.offset(2 as isize); + i = 0; + while i < len { + let mut x0: opus_val32 = 0.; + let mut x1: opus_val32 = 0.; + let mut out0: opus_val32 = 0.; + let mut out1: opus_val32 = 0.; + x0 = *in_0.offset((2 * i + 0) as isize); + x1 = *in_0.offset((2 * i + 1) as isize); + out0 = x0 - m0; + out1 = x1 - m2; + m0 = coef * x0 + VERY_SMALL + coef2 * m0; + m2 = coef * x1 + VERY_SMALL + coef2 * m2; + *out.offset((2 * i + 0) as isize) = out0; + *out.offset((2 * i + 1) as isize) = out1; + i += 1; + } + *hp_mem.offset(0 as isize) = m0; + *hp_mem.offset(2 as isize) = m2; + } else { + let mut m0_0: f32 = 0.; + m0_0 = *hp_mem.offset(0 as isize); + i = 0; + while i < len { + let mut x: opus_val32 = 0.; + let mut y: opus_val32 = 0.; + x = *in_0.offset(i as isize); + y = x - m0_0; + m0_0 = coef * x + VERY_SMALL + coef2 * m0_0; + *out.offset(i as isize) = y; + i += 1; + } + *hp_mem.offset(0 as isize) = m0_0; + }; +} +unsafe fn stereo_fade( + in_0: *const opus_val16, + out: *mut opus_val16, + mut g1: opus_val16, + mut g2: opus_val16, + overlap48: i32, + frame_size: i32, + channels: i32, + window: *const opus_val16, + Fs: i32, +) { + let mut i: i32 = 0; + let mut overlap: i32 = 0; + let mut inc: i32 = 0; + inc = 48000 / Fs; + overlap = overlap48 / inc; + g1 = Q15ONE - g1; + g2 = Q15ONE - g2; + i = 0; + while i < overlap { + let mut diff: opus_val32 = 0.; + let mut g: opus_val16 = 0.; + let mut w: opus_val16 = 0.; + w = *window.offset((i * inc) as isize) * *window.offset((i * inc) as isize); + g = w * g2 + (1.0f32 - w) * g1; + diff = 0.5f32 + * (*in_0.offset((i * channels) as isize) - *in_0.offset((i * channels + 1) as isize)); + diff = g * diff; + *out.offset((i * channels) as isize) = *out.offset((i * channels) as isize) - diff; + *out.offset((i * channels + 1) as isize) = *out.offset((i * channels + 1) as isize) + diff; + i += 1; + } + while i < frame_size { + let mut diff_0: opus_val32 = 0.; + diff_0 = 0.5f32 + * (*in_0.offset((i * channels) as isize) - *in_0.offset((i * channels + 1) as isize)); + diff_0 = g2 * diff_0; + *out.offset((i * channels) as isize) = *out.offset((i * channels) as isize) - diff_0; + *out.offset((i * channels + 1) as isize) = + *out.offset((i * channels + 1) as isize) + diff_0; + i += 1; + } +} +unsafe fn gain_fade( + in_0: *const opus_val16, + out: *mut opus_val16, + g1: opus_val16, + g2: opus_val16, + overlap48: i32, + frame_size: i32, + channels: i32, + window: *const opus_val16, + Fs: i32, +) { + let mut i: i32 = 0; + let mut inc: i32 = 0; + let mut overlap: i32 = 0; + let mut c: i32 = 0; + inc = 48000 / Fs; + overlap = overlap48 / inc; + if channels == 1 { + i = 0; + while i < overlap { + let mut g: opus_val16 = 0.; + let mut w: opus_val16 = 0.; + w = *window.offset((i * inc) as isize) * *window.offset((i * inc) as isize); + g = w * g2 + (1.0f32 - w) * g1; + *out.offset(i as isize) = g * *in_0.offset(i as isize); + i += 1; + } + } else { + i = 0; + while i < overlap { + let mut g_0: opus_val16 = 0.; + let mut w_0: opus_val16 = 0.; + w_0 = *window.offset((i * inc) as isize) * *window.offset((i * inc) as isize); + g_0 = w_0 * g2 + (1.0f32 - w_0) * g1; + *out.offset((i * 2) as isize) = g_0 * *in_0.offset((i * 2) as isize); + *out.offset((i * 2 + 1) as isize) = g_0 * *in_0.offset((i * 2 + 1) as isize); + i += 1; + } + } + c = 0; + loop { + i = overlap; + while i < frame_size { + *out.offset((i * channels + c) as isize) = + g2 * *in_0.offset((i * channels + c) as isize); + i += 1; + } + c += 1; + if !(c < channels) { + break; + } + } +} +pub unsafe fn opus_encoder_create( + Fs: i32, + channels: i32, + application: i32, + error: *mut i32, +) -> *mut OpusEncoder { + let mut ret: i32 = 0; + let mut st: *mut OpusEncoder = 0 as *mut OpusEncoder; + if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000 + || channels != 1 && channels != 2 + || application != OPUS_APPLICATION_VOIP + && application != OPUS_APPLICATION_AUDIO + && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY + { + if !error.is_null() { + *error = OPUS_BAD_ARG; + } + return NULL as *mut OpusEncoder; + } + st = malloc(opus_encoder_get_size(channels) as size_t) as *mut OpusEncoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusEncoder; + } + ret = opus_encoder_init(st, Fs, channels, application); + if !error.is_null() { + *error = ret; + } + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusEncoder; + } + return st; +} +unsafe fn user_bitrate_to_bitrate( + st: *mut OpusEncoder, + mut frame_size: i32, + max_data_bytes: i32, +) -> i32 { + if frame_size == 0 { + frame_size = (*st).Fs / 400; + } + if (*st).user_bitrate_bps == OPUS_AUTO { + return 60 * (*st).Fs / frame_size + (*st).Fs * (*st).channels; + } else if (*st).user_bitrate_bps == OPUS_BITRATE_MAX { + return max_data_bytes * 8 * (*st).Fs / frame_size; + } else { + return (*st).user_bitrate_bps; + }; +} +pub unsafe fn downmix_float( + mut _x: *const core::ffi::c_void, + y: *mut opus_val32, + subframe: i32, + offset: i32, + c1: i32, + c2: i32, + C: i32, +) { + let mut x: *const f32 = 0 as *const f32; + let mut j: i32 = 0; + x = _x as *const f32; + j = 0; + while j < subframe { + *y.offset(j as isize) = *x.offset(((j + offset) * C + c1) as isize) * CELT_SIG_SCALE; + j += 1; + } + if c2 > -1 { + j = 0; + while j < subframe { + let ref mut fresh0 = *y.offset(j as isize); + *fresh0 += *x.offset(((j + offset) * C + c2) as isize) * CELT_SIG_SCALE; + j += 1; + } + } else if c2 == -(2) { + let mut c: i32 = 0; + c = 1; + while c < C { + j = 0; + while j < subframe { + let ref mut fresh1 = *y.offset(j as isize); + *fresh1 += *x.offset(((j + offset) * C + c) as isize) * CELT_SIG_SCALE; + j += 1; + } + c += 1; + } + } +} +pub unsafe fn downmix_int( + mut _x: *const core::ffi::c_void, + y: *mut opus_val32, + subframe: i32, + offset: i32, + c1: i32, + c2: i32, + C: i32, +) { + let mut x: *const i16 = 0 as *const i16; + let mut j: i32 = 0; + x = _x as *const i16; + j = 0; + while j < subframe { + *y.offset(j as isize) = *x.offset(((j + offset) * C + c1) as isize) as opus_val32; + j += 1; + } + if c2 > -1 { + j = 0; + while j < subframe { + let ref mut fresh2 = *y.offset(j as isize); + *fresh2 += *x.offset(((j + offset) * C + c2) as isize) as i32 as f32; + j += 1; + } + } else if c2 == -(2) { + let mut c: i32 = 0; + c = 1; + while c < C { + j = 0; + while j < subframe { + let ref mut fresh3 = *y.offset(j as isize); + *fresh3 += *x.offset(((j + offset) * C + c) as isize) as i32 as f32; + j += 1; + } + c += 1; + } + } +} +pub unsafe fn frame_size_select(frame_size: i32, variable_duration: i32, Fs: i32) -> i32 { + let mut new_size: i32 = 0; + if frame_size < Fs / 400 { + return -1; + } + if variable_duration == OPUS_FRAMESIZE_ARG { + new_size = frame_size; + } else if variable_duration >= OPUS_FRAMESIZE_2_5_MS + && variable_duration <= OPUS_FRAMESIZE_120_MS + { + if variable_duration <= OPUS_FRAMESIZE_40_MS { + new_size = (Fs / 400) << variable_duration - OPUS_FRAMESIZE_2_5_MS; + } else { + new_size = (variable_duration - OPUS_FRAMESIZE_2_5_MS - 2) * Fs / 50; + } + } else { + return -1; + } + if new_size > frame_size { + return -1; + } + if 400 * new_size != Fs + && 200 * new_size != Fs + && 100 * new_size != Fs + && 50 * new_size != Fs + && 25 * new_size != Fs + && 50 * new_size != 3 * Fs + && 50 * new_size != 4 * Fs + && 50 * new_size != 5 * Fs + && 50 * new_size != 6 * Fs + { + return -1; + } + return new_size; +} +pub unsafe fn compute_stereo_width( + pcm: *const opus_val16, + frame_size: i32, + Fs: i32, + mem: *mut StereoWidthState, +) -> opus_val16 { + let mut xx: opus_val32 = 0.; + let mut xy: opus_val32 = 0.; + let mut yy: opus_val32 = 0.; + let mut sqrt_xx: opus_val16 = 0.; + let mut sqrt_yy: opus_val16 = 0.; + let mut qrrt_xx: opus_val16 = 0.; + let mut qrrt_yy: opus_val16 = 0.; + let mut frame_rate: i32 = 0; + let mut i: i32 = 0; + let mut short_alpha: opus_val16 = 0.; + frame_rate = Fs / frame_size; + short_alpha = + Q15ONE - 25 as opus_val32 * 1.0f32 / (if 50 > frame_rate { 50 } else { frame_rate }) as f32; + yy = 0 as opus_val32; + xy = yy; + xx = xy; + i = 0; + while i < frame_size - 3 { + let mut pxx: opus_val32 = 0 as opus_val32; + let mut pxy: opus_val32 = 0 as opus_val32; + let mut pyy: opus_val32 = 0 as opus_val32; + let mut x: opus_val16 = 0.; + let mut y: opus_val16 = 0.; + x = *pcm.offset((2 * i) as isize); + y = *pcm.offset((2 * i + 1) as isize); + pxx = x * x; + pxy = x * y; + pyy = y * y; + x = *pcm.offset((2 * i + 2) as isize); + y = *pcm.offset((2 * i + 3) as isize); + pxx += x * x; + pxy += x * y; + pyy += y * y; + x = *pcm.offset((2 * i + 4) as isize); + y = *pcm.offset((2 * i + 5) as isize); + pxx += x * x; + pxy += x * y; + pyy += y * y; + x = *pcm.offset((2 * i + 6) as isize); + y = *pcm.offset((2 * i + 7) as isize); + pxx += x * x; + pxy += x * y; + pyy += y * y; + xx += pxx; + xy += pxy; + yy += pyy; + i += 4; + } + if !(xx < 1e9f32) || xx != xx || !(yy < 1e9f32) || yy != yy { + yy = 0 as opus_val32; + xx = yy; + xy = xx; + } + (*mem).XX += short_alpha * (xx - (*mem).XX); + (*mem).XY += short_alpha * (xy - (*mem).XY); + (*mem).YY += short_alpha * (yy - (*mem).YY); + (*mem).XX = if 0 as f32 > (*mem).XX { + 0 as f32 + } else { + (*mem).XX + }; + (*mem).XY = if 0 as f32 > (*mem).XY { + 0 as f32 + } else { + (*mem).XY + }; + (*mem).YY = if 0 as f32 > (*mem).YY { + 0 as f32 + } else { + (*mem).YY + }; + if (if (*mem).XX > (*mem).YY { + (*mem).XX + } else { + (*mem).YY + }) > 8e-4f32 + { + let mut corr: opus_val16 = 0.; + let mut ldiff: opus_val16 = 0.; + let mut width: opus_val16 = 0.; + sqrt_xx = celt_sqrt((*mem).XX); + sqrt_yy = celt_sqrt((*mem).YY); + qrrt_xx = celt_sqrt(sqrt_xx); + qrrt_yy = celt_sqrt(sqrt_yy); + (*mem).XY = if (*mem).XY < sqrt_xx * sqrt_yy { + (*mem).XY + } else { + sqrt_xx * sqrt_yy + }; + corr = (*mem).XY / (1e-15f32 + sqrt_xx * sqrt_yy); + ldiff = 1.0f32 * (qrrt_xx - qrrt_yy).abs() / (EPSILON + qrrt_xx + qrrt_yy); + width = celt_sqrt(1.0f32 - corr * corr) * ldiff; + (*mem).smoothed_width += (width - (*mem).smoothed_width) / frame_rate as f32; + (*mem).max_follower = + if (*mem).max_follower - 0.02f32 / frame_rate as f32 > (*mem).smoothed_width { + (*mem).max_follower - 0.02f32 / frame_rate as f32 + } else { + (*mem).smoothed_width + }; + } + return if 1.0f32 < 20 as opus_val32 * (*mem).max_follower { + 1.0f32 + } else { + 20 as opus_val32 * (*mem).max_follower + }; +} +unsafe fn decide_fec( + useInBandFEC: i32, + PacketLoss_perc: i32, + last_fec: i32, + mode: i32, + bandwidth: *mut i32, + rate: i32, +) -> i32 { + let mut orig_bandwidth: i32 = 0; + if useInBandFEC == 0 || PacketLoss_perc == 0 || mode == MODE_CELT_ONLY { + return 0; + } + orig_bandwidth = *bandwidth; + loop { + let mut hysteresis: i32 = 0; + let mut LBRR_rate_thres_bps: i32 = 0; + LBRR_rate_thres_bps = + fec_thresholds[(2 * (*bandwidth - OPUS_BANDWIDTH_NARROWBAND)) as usize]; + hysteresis = fec_thresholds[(2 * (*bandwidth - OPUS_BANDWIDTH_NARROWBAND) + 1) as usize]; + if last_fec == 1 { + LBRR_rate_thres_bps -= hysteresis; + } + if last_fec == 0 { + LBRR_rate_thres_bps += hysteresis; + } + LBRR_rate_thres_bps = ((LBRR_rate_thres_bps + * (125 + - (if PacketLoss_perc < 25 { + PacketLoss_perc + } else { + 25 + }))) as i64 + * (0.01f64 * ((1) << 16) as f64 + 0.5f64) as i32 as i16 as i64 + >> 16) as i32; + if rate > LBRR_rate_thres_bps { + return 1; + } else if PacketLoss_perc <= 5 { + return 0; + } else { + if !(*bandwidth > OPUS_BANDWIDTH_NARROWBAND) { + break; + } + *bandwidth -= 1; + } + } + *bandwidth = orig_bandwidth; + return 0; +} +unsafe fn compute_silk_rate_for_hybrid( + mut rate: i32, + bandwidth: i32, + frame20ms: i32, + vbr: i32, + fec: i32, + channels: i32, +) -> i32 { + let mut entry: i32 = 0; + let mut i: i32 = 0; + let mut N: i32 = 0; + let mut silk_rate: i32 = 0; + static mut rate_table: [[i32; 5]; 7] = [ + [0, 0, 0, 0, 0], + [12000, 10000, 10000, 11000, 11000], + [16000, 13500, 13500, 15000, 15000], + [20000, 16000, 16000, 18000, 18000], + [24000, 18000, 18000, 21000, 21000], + [32000, 22000, 22000, 28000, 28000], + [64000, 38000, 38000, 50000, 50000], + ]; + rate /= channels; + entry = 1 + frame20ms + 2 * fec; + N = (::core::mem::size_of::<[[i32; 5]; 7]>() as u64) + .wrapping_div(::core::mem::size_of::<[i32; 5]>() as u64) as i32; + i = 1; + while i < N { + if rate_table[i as usize][0 as usize] > rate { + break; + } + i += 1; + } + if i == N { + silk_rate = rate_table[(i - 1) as usize][entry as usize]; + silk_rate += (rate - rate_table[(i - 1) as usize][0 as usize]) / 2; + } else { + let mut lo: i32 = 0; + let mut hi: i32 = 0; + let mut x0: i32 = 0; + let mut x1: i32 = 0; + lo = rate_table[(i - 1) as usize][entry as usize]; + hi = rate_table[i as usize][entry as usize]; + x0 = rate_table[(i - 1) as usize][0 as usize]; + x1 = rate_table[i as usize][0 as usize]; + silk_rate = (lo * (x1 - rate) + hi * (rate - x0)) / (x1 - x0); + } + if vbr == 0 { + silk_rate += 100; + } + if bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND { + silk_rate += 300; + } + silk_rate *= channels; + if channels == 2 && rate >= 12000 { + silk_rate -= 1000; + } + return silk_rate; +} +unsafe fn compute_equiv_rate( + bitrate: i32, + channels: i32, + frame_rate: i32, + vbr: i32, + mode: i32, + complexity: i32, + loss: i32, +) -> i32 { + let mut equiv: i32 = 0; + equiv = bitrate; + if frame_rate > 50 { + equiv -= (40 * channels + 20) * (frame_rate - 50); + } + if vbr == 0 { + equiv -= equiv / 12; + } + equiv = equiv * (90 + complexity) / 100; + if mode == MODE_SILK_ONLY || mode == MODE_HYBRID { + if complexity < 2 { + equiv = equiv * 4 / 5; + } + equiv -= equiv * loss / (6 * loss + 10); + } else if mode == MODE_CELT_ONLY { + if complexity < 5 { + equiv = equiv * 9 / 10; + } + } else { + equiv -= equiv * loss / (12 * loss + 20); + } + return equiv; +} +pub unsafe fn is_digital_silence( + pcm: *const opus_val16, + frame_size: i32, + channels: i32, + lsb_depth: i32, +) -> i32 { + let mut silence: i32 = 0; + let mut sample_max: opus_val32 = 0 as opus_val32; + sample_max = celt_maxabs16(pcm, frame_size * channels); + silence = (sample_max <= 1 as opus_val16 / ((1) << lsb_depth) as f32) as i32; + return silence; +} +unsafe fn compute_frame_energy( + pcm: *const opus_val16, + frame_size: i32, + channels: i32, + _arch: i32, +) -> opus_val32 { + let len: i32 = frame_size * channels; + return celt_inner_prod_c(pcm, pcm, len) / len as f32; +} +unsafe fn decide_dtx_mode( + activity_probability: f32, + nb_no_activity_frames: *mut i32, + peak_signal_energy: opus_val32, + pcm: *const opus_val16, + frame_size: i32, + channels: i32, + mut is_silence: i32, + arch: i32, +) -> i32 { + let mut noise_energy: opus_val32 = 0.; + if is_silence == 0 { + if activity_probability < DTX_ACTIVITY_THRESHOLD { + noise_energy = compute_frame_energy(pcm, frame_size, channels, arch); + is_silence = (peak_signal_energy >= PSEUDO_SNR_THRESHOLD * noise_energy) as i32; + } + } + if is_silence != 0 { + *nb_no_activity_frames += 1; + if *nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX { + if *nb_no_activity_frames <= NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX { + return 1; + } else { + *nb_no_activity_frames = NB_SPEECH_FRAMES_BEFORE_DTX; + } + } + } else { + *nb_no_activity_frames = 0; + } + return 0; +} +unsafe fn encode_multiframe_packet( + st: *mut OpusEncoder, + pcm: *const opus_val16, + nb_frames: i32, + frame_size: i32, + data: *mut u8, + out_data_bytes: i32, + to_celt: i32, + lsb_depth: i32, + float_api: i32, +) -> i32 { + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut bak_mode: i32 = 0; + let mut bak_bandwidth: i32 = 0; + let mut bak_channels: i32 = 0; + let mut bak_to_mono: i32 = 0; + let mut max_header_bytes: i32 = 0; + let mut bytes_per_frame: i32 = 0; + let mut cbr_bytes: i32 = 0; + let mut repacketize_len: i32 = 0; + let mut tmp_len: i32 = 0; + max_header_bytes = if nb_frames == 2 { + 3 + } else { + 2 + (nb_frames - 1) * 2 + }; + if (*st).use_vbr != 0 || (*st).user_bitrate_bps == OPUS_BITRATE_MAX { + repacketize_len = out_data_bytes; + } else { + cbr_bytes = 3 * (*st).bitrate_bps / (3 * 8 * (*st).Fs / (frame_size * nb_frames)); + repacketize_len = if cbr_bytes < out_data_bytes { + cbr_bytes + } else { + out_data_bytes + }; + } + bytes_per_frame = if (1276) < 1 + (repacketize_len - max_header_bytes) / nb_frames { + 1276 + } else { + 1 + (repacketize_len - max_header_bytes) / nb_frames + }; + let vla = (nb_frames * bytes_per_frame) as usize; + let mut tmp_data: Vec = ::std::vec::from_elem(0, vla); + let mut rp: [OpusRepacketizer; 1] = [OpusRepacketizer { + toc: 0, + nb_frames: 0, + frames: [0 as *const u8; 48], + len: [0; 48], + framesize: 0, + }; 1]; + opus_repacketizer_init(rp.as_mut_ptr()); + bak_mode = (*st).user_forced_mode; + bak_bandwidth = (*st).user_bandwidth; + bak_channels = (*st).force_channels; + (*st).user_forced_mode = (*st).mode; + (*st).user_bandwidth = (*st).bandwidth; + (*st).force_channels = (*st).stream_channels; + bak_to_mono = (*st).silk_mode.toMono; + if bak_to_mono != 0 { + (*st).force_channels = 1; + } else { + (*st).prev_channels = (*st).stream_channels; + } + i = 0; + while i < nb_frames { + (*st).silk_mode.toMono = 0; + (*st).nonfinal_frame = (i < nb_frames - 1) as i32; + if to_celt != 0 && i == nb_frames - 1 { + (*st).user_forced_mode = MODE_CELT_ONLY; + } + tmp_len = opus_encode_native( + st, + pcm.offset((i * ((*st).channels * frame_size)) as isize), + frame_size, + tmp_data.as_mut_ptr().offset((i * bytes_per_frame) as isize), + bytes_per_frame, + lsb_depth, + NULL as *const core::ffi::c_void, + 0, + 0, + 0, + 0, + None, + float_api, + ); + if tmp_len < 0 { + return OPUS_INTERNAL_ERROR; + } + ret = opus_repacketizer_cat( + rp.as_mut_ptr(), + tmp_data.as_mut_ptr().offset((i * bytes_per_frame) as isize), + tmp_len, + ); + if ret < 0 { + return OPUS_INTERNAL_ERROR; + } + i += 1; + } + ret = opus_repacketizer_out_range_impl( + rp.as_mut_ptr(), + 0, + nb_frames, + data, + repacketize_len, + 0, + ((*st).use_vbr == 0) as i32, + ); + if ret < 0 { + return OPUS_INTERNAL_ERROR; + } + (*st).user_forced_mode = bak_mode; + (*st).user_bandwidth = bak_bandwidth; + (*st).force_channels = bak_channels; + (*st).silk_mode.toMono = bak_to_mono; + return ret; +} +unsafe fn compute_redundancy_bytes( + max_data_bytes: i32, + bitrate_bps: i32, + frame_rate: i32, + channels: i32, +) -> i32 { + let mut redundancy_bytes_cap: i32 = 0; + let mut redundancy_bytes: i32 = 0; + let mut redundancy_rate: i32 = 0; + let mut base_bits: i32 = 0; + let mut available_bits: i32 = 0; + base_bits = 40 * channels + 20; + redundancy_rate = bitrate_bps + base_bits * (200 - frame_rate); + redundancy_rate = 3 * redundancy_rate / 2; + redundancy_bytes = redundancy_rate / 1600; + available_bits = max_data_bytes * 8 - 2 * base_bits; + redundancy_bytes_cap = (available_bits * 240 / (240 + 48000 / frame_rate) + base_bits) / 8; + redundancy_bytes = if redundancy_bytes < redundancy_bytes_cap { + redundancy_bytes + } else { + redundancy_bytes_cap + }; + if redundancy_bytes > 4 + 8 * channels { + redundancy_bytes = if (257) < redundancy_bytes { + 257 + } else { + redundancy_bytes + }; + } else { + redundancy_bytes = 0; + } + return redundancy_bytes; +} +pub unsafe fn opus_encode_native( + st: *mut OpusEncoder, + pcm: *const opus_val16, + frame_size: i32, + mut data: *mut u8, + out_data_bytes: i32, + mut lsb_depth: i32, + analysis_pcm: *const core::ffi::c_void, + analysis_size: i32, + c1: i32, + c2: i32, + analysis_channels: i32, + downmix: downmix_func, + float_api: i32, +) -> i32 { + let mut silk_enc: *mut core::ffi::c_void = 0 as *mut core::ffi::c_void; + let mut celt_enc: *mut OpusCustomEncoder = 0 as *mut OpusCustomEncoder; + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut nBytes: i32 = 0; + let mut enc: ec_enc = ec_enc { + buf: &mut [], + storage: 0, + end_offs: 0, + end_window: 0, + nend_bits: 0, + nbits_total: 0, + offs: 0, + rng: 0, + val: 0, + ext: 0, + rem: 0, + error: 0, + }; + let mut bytes_target: i32 = 0; + let mut prefill: i32 = 0; + let mut start_band: i32 = 0; + let mut redundancy: i32 = 0; + let mut redundancy_bytes: i32 = 0; + let mut celt_to_silk: i32 = 0; + let mut nb_compr_bytes: i32 = 0; + let mut to_celt: i32 = 0; + let mut redundant_rng: u32 = 0; + let mut cutoff_Hz: i32 = 0; + let mut hp_freq_smth1: i32 = 0; + let mut voice_est: i32 = 0; + let mut equiv_rate: i32 = 0; + let mut delay_compensation: i32 = 0; + let mut frame_rate: i32 = 0; + let mut max_rate: i32 = 0; + let mut curr_bandwidth: i32 = 0; + let mut HB_gain: opus_val16 = 0.; + let mut max_data_bytes: i32 = 0; + let mut total_buffer: i32 = 0; + let mut stereo_width: opus_val16 = 0.; + let mut celt_mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut analysis_info: AnalysisInfo = AnalysisInfo { + valid: 0, + tonality: 0., + tonality_slope: 0., + noisiness: 0., + activity: 0., + music_prob: 0., + music_prob_min: 0., + music_prob_max: 0., + bandwidth: 0, + activity_probability: 0., + max_pitch_ratio: 0., + leak_boost: [0; 19], + }; + let mut analysis_read_pos_bak: i32 = -1; + let mut analysis_read_subframe_bak: i32 = -1; + let mut is_silence: i32 = 0; + max_data_bytes = if (1276) < out_data_bytes { + 1276 + } else { + out_data_bytes + }; + (*st).rangeFinal = 0; + if frame_size <= 0 || max_data_bytes <= 0 { + return OPUS_BAD_ARG; + } + if max_data_bytes == 1 && (*st).Fs == frame_size * 10 { + return OPUS_BUFFER_TOO_SMALL; + } + silk_enc = (st as *mut i8).offset((*st).silk_enc_offset as isize) as *mut core::ffi::c_void; + celt_enc = (st as *mut i8).offset((*st).celt_enc_offset as isize) as *mut OpusCustomEncoder; + if (*st).application == OPUS_APPLICATION_RESTRICTED_LOWDELAY { + delay_compensation = 0; + } else { + delay_compensation = (*st).delay_compensation; + } + lsb_depth = if lsb_depth < (*st).lsb_depth { + lsb_depth + } else { + (*st).lsb_depth + }; + opus_custom_encoder_ctl!(celt_enc, CELT_GET_MODE_REQUEST, &mut celt_mode); + analysis_info.valid = 0; + if (*st).silk_mode.complexity >= 7 && (*st).Fs >= 16000 { + is_silence = is_digital_silence(pcm, frame_size, (*st).channels, lsb_depth); + analysis_read_pos_bak = (*st).analysis.read_pos; + analysis_read_subframe_bak = (*st).analysis.read_subframe; + run_analysis( + &mut (*st).analysis, + celt_mode, + analysis_pcm, + analysis_size, + frame_size, + c1, + c2, + analysis_channels, + (*st).Fs, + lsb_depth, + downmix, + &mut analysis_info, + ); + if is_silence == 0 && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD { + (*st).peak_signal_energy = if 0.999f32 * (*st).peak_signal_energy + > compute_frame_energy(pcm, frame_size, (*st).channels, (*st).arch) + { + 0.999f32 * (*st).peak_signal_energy + } else { + compute_frame_energy(pcm, frame_size, (*st).channels, (*st).arch) + }; + } + } else if (*st).analysis.initialized != 0 { + tonality_analysis_reset(&mut (*st).analysis); + } + if is_silence == 0 { + (*st).voice_ratio = -1; + } + (*st).detected_bandwidth = 0; + if analysis_info.valid != 0 { + let mut analysis_bandwidth: i32 = 0; + if (*st).signal_type == OPUS_AUTO { + let mut prob: f32 = 0.; + if (*st).prev_mode == 0 { + prob = analysis_info.music_prob; + } else if (*st).prev_mode == MODE_CELT_ONLY { + prob = analysis_info.music_prob_max; + } else { + prob = analysis_info.music_prob_min; + } + (*st).voice_ratio = (0.5 + (100.0 * (1.0 - prob))).floor() as i32; + } + analysis_bandwidth = analysis_info.bandwidth; + if analysis_bandwidth <= 12 { + (*st).detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } else if analysis_bandwidth <= 14 { + (*st).detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + } else if analysis_bandwidth <= 16 { + (*st).detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } else if analysis_bandwidth <= 18 { + (*st).detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + } else { + (*st).detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + } + } + if (*st).channels == 2 && (*st).force_channels != 1 { + stereo_width = compute_stereo_width(pcm, frame_size, (*st).Fs, &mut (*st).width_mem); + } else { + stereo_width = 0 as opus_val16; + } + total_buffer = delay_compensation; + (*st).bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); + frame_rate = (*st).Fs / frame_size; + if (*st).use_vbr == 0 { + let mut cbrBytes: i32 = 0; + let frame_rate12: i32 = 12 * (*st).Fs / frame_size; + cbrBytes = + if (12 * (*st).bitrate_bps / 8 + frame_rate12 / 2) / frame_rate12 < max_data_bytes { + (12 * (*st).bitrate_bps / 8 + frame_rate12 / 2) / frame_rate12 + } else { + max_data_bytes + }; + (*st).bitrate_bps = cbrBytes * frame_rate12 * 8 / 12; + max_data_bytes = if 1 > cbrBytes { 1 } else { cbrBytes }; + } + if max_data_bytes < 3 + || (*st).bitrate_bps < 3 * frame_rate * 8 + || frame_rate < 50 && (max_data_bytes * frame_rate < 300 || (*st).bitrate_bps < 2400) + { + let mut tocmode: i32 = (*st).mode; + let mut bw: i32 = if (*st).bandwidth == 0 { + OPUS_BANDWIDTH_NARROWBAND + } else { + (*st).bandwidth + }; + let mut packet_code: i32 = 0; + let mut num_multiframes: i32 = 0; + if tocmode == 0 { + tocmode = MODE_SILK_ONLY; + } + if frame_rate > 100 { + tocmode = MODE_CELT_ONLY; + } + if frame_rate == 25 && tocmode != MODE_SILK_ONLY { + frame_rate = 50; + packet_code = 1; + } + if frame_rate <= 16 { + if out_data_bytes == 1 || tocmode == MODE_SILK_ONLY && frame_rate != 10 { + tocmode = MODE_SILK_ONLY; + packet_code = (frame_rate <= 12) as i32; + frame_rate = if frame_rate == 12 { 25 } else { 16 }; + } else { + num_multiframes = 50 / frame_rate; + frame_rate = 50; + packet_code = 3; + } + } + if tocmode == MODE_SILK_ONLY && bw > OPUS_BANDWIDTH_WIDEBAND { + bw = OPUS_BANDWIDTH_WIDEBAND; + } else if tocmode == MODE_CELT_ONLY && bw == OPUS_BANDWIDTH_MEDIUMBAND { + bw = OPUS_BANDWIDTH_NARROWBAND; + } else if tocmode == MODE_HYBRID && bw <= OPUS_BANDWIDTH_SUPERWIDEBAND { + bw = OPUS_BANDWIDTH_SUPERWIDEBAND; + } + *data.offset(0 as isize) = gen_toc(tocmode, frame_rate, bw, (*st).stream_channels); + let ref mut fresh4 = *data.offset(0 as isize); + *fresh4 = (*fresh4 as i32 | packet_code) as u8; + ret = if packet_code <= 1 { 1 } else { 2 }; + max_data_bytes = if max_data_bytes > ret { + max_data_bytes + } else { + ret + }; + if packet_code == 3 { + *data.offset(1 as isize) = num_multiframes as u8; + } + if (*st).use_vbr == 0 { + ret = opus_packet_pad(data, ret, max_data_bytes); + if ret == OPUS_OK { + ret = max_data_bytes; + } else { + ret = OPUS_INTERNAL_ERROR; + } + } + return ret; + } + max_rate = frame_rate * max_data_bytes * 8; + equiv_rate = compute_equiv_rate( + (*st).bitrate_bps, + (*st).channels, + (*st).Fs / frame_size, + (*st).use_vbr, + 0, + (*st).silk_mode.complexity, + (*st).silk_mode.packetLossPercentage, + ); + if (*st).signal_type == OPUS_SIGNAL_VOICE { + voice_est = 127; + } else if (*st).signal_type == OPUS_SIGNAL_MUSIC { + voice_est = 0; + } else if (*st).voice_ratio >= 0 { + voice_est = (*st).voice_ratio * 327 >> 8; + if (*st).application == OPUS_APPLICATION_AUDIO { + voice_est = if voice_est < 115 { voice_est } else { 115 }; + } + } else if (*st).application == OPUS_APPLICATION_VOIP { + voice_est = 115; + } else { + voice_est = 48; + } + if (*st).force_channels != OPUS_AUTO && (*st).channels == 2 { + (*st).stream_channels = (*st).force_channels; + } else if (*st).channels == 2 { + let mut stereo_threshold: i32 = 0; + stereo_threshold = stereo_music_threshold + + (voice_est * voice_est * (stereo_voice_threshold - stereo_music_threshold) >> 14); + if (*st).stream_channels == 2 { + stereo_threshold -= 1000; + } else { + stereo_threshold += 1000; + } + (*st).stream_channels = if equiv_rate > stereo_threshold { 2 } else { 1 }; + } else { + (*st).stream_channels = (*st).channels; + } + equiv_rate = compute_equiv_rate( + (*st).bitrate_bps, + (*st).stream_channels, + (*st).Fs / frame_size, + (*st).use_vbr, + 0, + (*st).silk_mode.complexity, + (*st).silk_mode.packetLossPercentage, + ); + (*st).silk_mode.useDTX = + ((*st).use_dtx != 0 && !(analysis_info.valid != 0 || is_silence != 0)) as i32; + if (*st).application == OPUS_APPLICATION_RESTRICTED_LOWDELAY { + (*st).mode = MODE_CELT_ONLY; + } else if (*st).user_forced_mode == OPUS_AUTO { + let mut mode_voice: i32 = 0; + let mut mode_music: i32 = 0; + let mut threshold: i32 = 0; + mode_voice = ((1.0f32 - stereo_width) * mode_thresholds[0 as usize][0 as usize] as f32 + + stereo_width * mode_thresholds[1 as usize][0 as usize] as f32) + as i32; + mode_music = ((1.0f32 - stereo_width) * mode_thresholds[1 as usize][1 as usize] as f32 + + stereo_width * mode_thresholds[1 as usize][1 as usize] as f32) + as i32; + threshold = mode_music + (voice_est * voice_est * (mode_voice - mode_music) >> 14); + if (*st).application == OPUS_APPLICATION_VOIP { + threshold += 8000; + } + if (*st).prev_mode == MODE_CELT_ONLY { + threshold -= 4000; + } else if (*st).prev_mode > 0 { + threshold += 4000; + } + (*st).mode = if equiv_rate >= threshold { + MODE_CELT_ONLY + } else { + MODE_SILK_ONLY + }; + if (*st).silk_mode.useInBandFEC != 0 + && (*st).silk_mode.packetLossPercentage > 128 - voice_est >> 4 + { + (*st).mode = MODE_SILK_ONLY; + } + if (*st).silk_mode.useDTX != 0 && voice_est > 100 { + (*st).mode = MODE_SILK_ONLY; + } + if max_data_bytes + < (if frame_rate > 50 { 9000 } else { 6000 }) * frame_size / ((*st).Fs * 8) + { + (*st).mode = MODE_CELT_ONLY; + } + } else { + (*st).mode = (*st).user_forced_mode; + } + if (*st).mode != MODE_CELT_ONLY && frame_size < (*st).Fs / 100 { + (*st).mode = MODE_CELT_ONLY; + } + if (*st).lfe != 0 { + (*st).mode = MODE_CELT_ONLY; + } + if (*st).prev_mode > 0 + && ((*st).mode != MODE_CELT_ONLY && (*st).prev_mode == MODE_CELT_ONLY + || (*st).mode == MODE_CELT_ONLY && (*st).prev_mode != MODE_CELT_ONLY) + { + redundancy = 1; + celt_to_silk = ((*st).mode != MODE_CELT_ONLY) as i32; + if celt_to_silk == 0 { + if frame_size >= (*st).Fs / 100 { + (*st).mode = (*st).prev_mode; + to_celt = 1; + } else { + redundancy = 0; + } + } + } + if (*st).stream_channels == 1 + && (*st).prev_channels == 2 + && (*st).silk_mode.toMono == 0 + && (*st).mode != MODE_CELT_ONLY + && (*st).prev_mode != MODE_CELT_ONLY + { + (*st).silk_mode.toMono = 1; + (*st).stream_channels = 2; + } else { + (*st).silk_mode.toMono = 0; + } + equiv_rate = compute_equiv_rate( + (*st).bitrate_bps, + (*st).stream_channels, + (*st).Fs / frame_size, + (*st).use_vbr, + (*st).mode, + (*st).silk_mode.complexity, + (*st).silk_mode.packetLossPercentage, + ); + if (*st).mode != MODE_CELT_ONLY && (*st).prev_mode == MODE_CELT_ONLY { + let mut dummy: silk_EncControlStruct = silk_EncControlStruct { + nChannelsAPI: 0, + nChannelsInternal: 0, + API_sampleRate: 0, + maxInternalSampleRate: 0, + minInternalSampleRate: 0, + desiredInternalSampleRate: 0, + payloadSize_ms: 0, + bitRate: 0, + packetLossPercentage: 0, + complexity: 0, + useInBandFEC: 0, + LBRR_coded: 0, + useDTX: 0, + useCBR: 0, + maxBits: 0, + toMono: 0, + opusCanSwitch: 0, + reducedDependency: 0, + internalSampleRate: 0, + allowBandwidthSwitch: 0, + inWBmodeWithoutVariableLP: 0, + stereoWidth_Q14: 0, + switchReady: 0, + signalType: 0, + offset: 0, + }; + silk_InitEncoder(silk_enc, (*st).arch, &mut dummy); + prefill = 1; + } + if (*st).mode == MODE_CELT_ONLY || (*st).first != 0 || (*st).silk_mode.allowBandwidthSwitch != 0 + { + let mut voice_bandwidth_thresholds: *const i32 = 0 as *const i32; + let mut music_bandwidth_thresholds: *const i32 = 0 as *const i32; + let mut bandwidth_thresholds: [i32; 8] = [0; 8]; + let mut bandwidth: i32 = OPUS_BANDWIDTH_FULLBAND; + if (*st).channels == 2 && (*st).force_channels != 1 { + voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds.as_ptr(); + music_bandwidth_thresholds = stereo_music_bandwidth_thresholds.as_ptr(); + } else { + voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds.as_ptr(); + music_bandwidth_thresholds = mono_music_bandwidth_thresholds.as_ptr(); + } + i = 0; + while i < 8 { + bandwidth_thresholds[i as usize] = *music_bandwidth_thresholds.offset(i as isize) + + (voice_est + * voice_est + * (*voice_bandwidth_thresholds.offset(i as isize) + - *music_bandwidth_thresholds.offset(i as isize)) + >> 14); + i += 1; + } + loop { + let mut threshold_0: i32 = 0; + let mut hysteresis: i32 = 0; + threshold_0 = + bandwidth_thresholds[(2 * (bandwidth - OPUS_BANDWIDTH_MEDIUMBAND)) as usize]; + hysteresis = + bandwidth_thresholds[(2 * (bandwidth - OPUS_BANDWIDTH_MEDIUMBAND) + 1) as usize]; + if (*st).first == 0 { + if (*st).auto_bandwidth >= bandwidth { + threshold_0 -= hysteresis; + } else { + threshold_0 += hysteresis; + } + } + if equiv_rate >= threshold_0 { + break; + } + bandwidth -= 1; + if !(bandwidth > OPUS_BANDWIDTH_NARROWBAND) { + break; + } + } + if bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + (*st).auto_bandwidth = bandwidth; + (*st).bandwidth = (*st).auto_bandwidth; + if (*st).first == 0 + && (*st).mode != MODE_CELT_ONLY + && (*st).silk_mode.inWBmodeWithoutVariableLP == 0 + && (*st).bandwidth > OPUS_BANDWIDTH_WIDEBAND + { + (*st).bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + } + if (*st).bandwidth > (*st).max_bandwidth { + (*st).bandwidth = (*st).max_bandwidth; + } + if (*st).user_bandwidth != OPUS_AUTO { + (*st).bandwidth = (*st).user_bandwidth; + } + if (*st).mode != MODE_CELT_ONLY && max_rate < 15000 { + (*st).bandwidth = if (*st).bandwidth < 1103 { + (*st).bandwidth + } else { + 1103 + }; + } + if (*st).Fs <= 24000 && (*st).bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND { + (*st).bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + } + if (*st).Fs <= 16000 && (*st).bandwidth > OPUS_BANDWIDTH_WIDEBAND { + (*st).bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + if (*st).Fs <= 12000 && (*st).bandwidth > OPUS_BANDWIDTH_MEDIUMBAND { + (*st).bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + } + if (*st).Fs <= 8000 && (*st).bandwidth > OPUS_BANDWIDTH_NARROWBAND { + (*st).bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } + if (*st).detected_bandwidth != 0 && (*st).user_bandwidth == OPUS_AUTO { + let mut min_detected_bandwidth: i32 = 0; + if equiv_rate <= 18000 * (*st).stream_channels && (*st).mode == MODE_CELT_ONLY { + min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } else if equiv_rate <= 24000 * (*st).stream_channels && (*st).mode == MODE_CELT_ONLY { + min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + } else if equiv_rate <= 30000 * (*st).stream_channels { + min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } else if equiv_rate <= 44000 * (*st).stream_channels { + min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + } else { + min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + } + (*st).detected_bandwidth = if (*st).detected_bandwidth > min_detected_bandwidth { + (*st).detected_bandwidth + } else { + min_detected_bandwidth + }; + (*st).bandwidth = if (*st).bandwidth < (*st).detected_bandwidth { + (*st).bandwidth + } else { + (*st).detected_bandwidth + }; + } + (*st).silk_mode.LBRR_coded = decide_fec( + (*st).silk_mode.useInBandFEC, + (*st).silk_mode.packetLossPercentage, + (*st).silk_mode.LBRR_coded, + (*st).mode, + &mut (*st).bandwidth, + equiv_rate, + ); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_LSB_DEPTH_REQUEST, lsb_depth); + if (*st).mode == MODE_CELT_ONLY && (*st).bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + (*st).bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + if (*st).lfe != 0 { + (*st).bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } + curr_bandwidth = (*st).bandwidth; + if (*st).mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND { + (*st).mode = MODE_HYBRID; + } + if (*st).mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND { + (*st).mode = MODE_SILK_ONLY; + } + if frame_size > (*st).Fs / 50 && (*st).mode != MODE_SILK_ONLY || frame_size > 3 * (*st).Fs / 50 + { + let mut enc_frame_size: i32 = 0; + let mut nb_frames: i32 = 0; + if (*st).mode == MODE_SILK_ONLY { + if frame_size == 2 * (*st).Fs / 25 { + enc_frame_size = (*st).Fs / 25; + } else if frame_size == 3 * (*st).Fs / 25 { + enc_frame_size = 3 * (*st).Fs / 50; + } else { + enc_frame_size = (*st).Fs / 50; + } + } else { + enc_frame_size = (*st).Fs / 50; + } + nb_frames = frame_size / enc_frame_size; + if analysis_read_pos_bak != -1 { + (*st).analysis.read_pos = analysis_read_pos_bak; + (*st).analysis.read_subframe = analysis_read_subframe_bak; + } + ret = encode_multiframe_packet( + st, + pcm, + nb_frames, + enc_frame_size, + data, + out_data_bytes, + to_celt, + lsb_depth, + float_api, + ); + return ret; + } + if (*st).silk_bw_switch != 0 { + redundancy = 1; + celt_to_silk = 1; + (*st).silk_bw_switch = 0; + prefill = 2; + } + if (*st).mode == MODE_CELT_ONLY { + redundancy = 0; + } + if redundancy != 0 { + redundancy_bytes = compute_redundancy_bytes( + max_data_bytes, + (*st).bitrate_bps, + frame_rate, + (*st).stream_channels, + ); + if redundancy_bytes == 0 { + redundancy = 0; + } + } + bytes_target = + (if max_data_bytes - redundancy_bytes < (*st).bitrate_bps * frame_size / ((*st).Fs * 8) { + max_data_bytes - redundancy_bytes + } else { + (*st).bitrate_bps * frame_size / ((*st).Fs * 8) + }) - 1; + data = data.offset(1 as isize); + enc = ec_enc_init(std::slice::from_raw_parts_mut( + data, + (max_data_bytes - 1) as usize, + )); + let vla = ((total_buffer + frame_size) * (*st).channels) as usize; + let mut pcm_buf: Vec = ::std::vec::from_elem(0., vla); + memcpy( + pcm_buf.as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*st).delay_buffer) + .as_mut_ptr() + .offset((((*st).encoder_buffer - total_buffer) * (*st).channels) as isize) + as *mut opus_val16 as *const core::ffi::c_void, + ((total_buffer * (*st).channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * pcm_buf.as_mut_ptr().offset_from( + &mut *((*st).delay_buffer) + .as_mut_ptr() + .offset((((*st).encoder_buffer - total_buffer) * (*st).channels) as isize), + ) as i64) as u64, + ), + ); + if (*st).mode == MODE_CELT_ONLY { + hp_freq_smth1 = ((silk_lin2log(60) as u32) << 8) as i32; + } else { + hp_freq_smth1 = (*(silk_enc as *mut silk_encoder)).state_Fxx[0 as usize] + .sCmn + .variable_HP_smth1_Q15; + } + (*st).variable_HP_smth2_Q15 = ((*st).variable_HP_smth2_Q15 as i64 + + ((hp_freq_smth1 - (*st).variable_HP_smth2_Q15) as i64 + * ((0.015f32 * ((1) << 16) as f32) as f64 + 0.5f64) as i32 as i16 as i64 + >> 16)) as i32; + cutoff_Hz = silk_log2lin((*st).variable_HP_smth2_Q15 >> 8); + if (*st).application == OPUS_APPLICATION_VOIP { + hp_cutoff( + pcm, + cutoff_Hz, + &mut *pcm_buf + .as_mut_ptr() + .offset((total_buffer * (*st).channels) as isize), + ((*st).hp_mem).as_mut_ptr(), + frame_size, + (*st).channels, + (*st).Fs, + (*st).arch, + ); + } else { + dc_reject( + pcm, + 3, + &mut *pcm_buf + .as_mut_ptr() + .offset((total_buffer * (*st).channels) as isize), + ((*st).hp_mem).as_mut_ptr(), + frame_size, + (*st).channels, + (*st).Fs, + ); + } + if float_api != 0 { + let mut sum: opus_val32 = 0.; + sum = celt_inner_prod_c( + &mut *pcm_buf + .as_mut_ptr() + .offset((total_buffer * (*st).channels) as isize), + &mut *pcm_buf + .as_mut_ptr() + .offset((total_buffer * (*st).channels) as isize), + frame_size * (*st).channels, + ); + if !(sum < 1e9f32) || sum != sum { + memset( + &mut *pcm_buf + .as_mut_ptr() + .offset((total_buffer * (*st).channels) as isize) + as *mut opus_val16 as *mut core::ffi::c_void, + 0, + ((frame_size * (*st).channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + (*st).hp_mem[3 as usize] = 0 as opus_val32; + (*st).hp_mem[2 as usize] = (*st).hp_mem[3 as usize]; + (*st).hp_mem[1 as usize] = (*st).hp_mem[2 as usize]; + (*st).hp_mem[0 as usize] = (*st).hp_mem[1 as usize]; + } + } + HB_gain = Q15ONE; + if (*st).mode != MODE_CELT_ONLY { + let mut total_bitRate: i32 = 0; + let mut celt_rate: i32 = 0; + let mut activity: i32 = 0; + let vla_0 = ((*st).channels * frame_size) as usize; + let mut pcm_silk: Vec = ::std::vec::from_elem(0, vla_0); + activity = VAD_NO_DECISION; + if analysis_info.valid != 0 { + activity = (analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD) as i32; + } + total_bitRate = 8 * bytes_target * frame_rate; + if (*st).mode == MODE_HYBRID { + (*st).silk_mode.bitRate = compute_silk_rate_for_hybrid( + total_bitRate, + curr_bandwidth, + ((*st).Fs == 50 * frame_size) as i32, + (*st).use_vbr, + (*st).silk_mode.LBRR_coded, + (*st).stream_channels, + ); + if ((*st).energy_masking).is_null() { + celt_rate = total_bitRate - (*st).silk_mode.bitRate; + HB_gain = Q15ONE - celt_exp2(-celt_rate as f32 * (1.0f32 / 1024f32)); + } + } else { + (*st).silk_mode.bitRate = total_bitRate; + } + if !((*st).energy_masking).is_null() && (*st).use_vbr != 0 && (*st).lfe == 0 { + let mut mask_sum: opus_val32 = 0 as opus_val32; + let mut masking_depth: opus_val16 = 0.; + let mut rate_offset: i32 = 0; + let mut c: i32 = 0; + let mut end: i32 = 17; + let mut srate: i16 = 16000; + if (*st).bandwidth == OPUS_BANDWIDTH_NARROWBAND { + end = 13; + srate = 8000; + } else if (*st).bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + end = 15; + srate = 12000; + } + c = 0; + while c < (*st).channels { + i = 0; + while i < end { + let mut mask: opus_val16 = 0.; + mask = if (if *((*st).energy_masking).offset((21 * c + i) as isize) < 0.5f32 { + *((*st).energy_masking).offset((21 * c + i) as isize) + } else { + 0.5f32 + }) > -2.0f32 + { + if *((*st).energy_masking).offset((21 * c + i) as isize) < 0.5f32 { + *((*st).energy_masking).offset((21 * c + i) as isize) + } else { + 0.5f32 + } + } else { + -2.0f32 + }; + if mask > 0 as f32 { + mask = 0.5f32 * mask; + } + mask_sum += mask; + i += 1; + } + c += 1; + } + masking_depth = mask_sum / end as f32 * (*st).channels as f32; + masking_depth += 0.2f32; + rate_offset = (srate as opus_val32 * masking_depth) as i32; + rate_offset = if rate_offset > -(2) * (*st).silk_mode.bitRate / 3 { + rate_offset + } else { + -(2) * (*st).silk_mode.bitRate / 3 + }; + if (*st).bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND + || (*st).bandwidth == OPUS_BANDWIDTH_FULLBAND + { + (*st).silk_mode.bitRate += 3 * rate_offset / 5; + } else { + (*st).silk_mode.bitRate += rate_offset; + } + } + (*st).silk_mode.payloadSize_ms = 1000 * frame_size / (*st).Fs; + (*st).silk_mode.nChannelsAPI = (*st).channels; + (*st).silk_mode.nChannelsInternal = (*st).stream_channels; + if curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND { + (*st).silk_mode.desiredInternalSampleRate = 8000; + } else if curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + (*st).silk_mode.desiredInternalSampleRate = 12000; + } else { + assert!((*st).mode == 1001 || curr_bandwidth == 1103); + (*st).silk_mode.desiredInternalSampleRate = 16000; + } + if (*st).mode == MODE_HYBRID { + (*st).silk_mode.minInternalSampleRate = 16000; + } else { + (*st).silk_mode.minInternalSampleRate = 8000; + } + (*st).silk_mode.maxInternalSampleRate = 16000; + if (*st).mode == MODE_SILK_ONLY { + let mut effective_max_rate: i32 = max_rate; + if frame_rate > 50 { + effective_max_rate = effective_max_rate * 2 / 3; + } + if effective_max_rate < 8000 { + (*st).silk_mode.maxInternalSampleRate = 12000; + (*st).silk_mode.desiredInternalSampleRate = + if (12000) < (*st).silk_mode.desiredInternalSampleRate { + 12000 + } else { + (*st).silk_mode.desiredInternalSampleRate + }; + } + if effective_max_rate < 7000 { + (*st).silk_mode.maxInternalSampleRate = 8000; + (*st).silk_mode.desiredInternalSampleRate = + if (8000) < (*st).silk_mode.desiredInternalSampleRate { + 8000 + } else { + (*st).silk_mode.desiredInternalSampleRate + }; + } + } + (*st).silk_mode.useCBR = ((*st).use_vbr == 0) as i32; + (*st).silk_mode.maxBits = (max_data_bytes - 1) * 8; + if redundancy != 0 && redundancy_bytes >= 2 { + (*st).silk_mode.maxBits -= redundancy_bytes * 8 + 1; + if (*st).mode == MODE_HYBRID { + (*st).silk_mode.maxBits -= 20; + } + } + if (*st).silk_mode.useCBR != 0 { + if (*st).mode == MODE_HYBRID { + (*st).silk_mode.maxBits = + if (*st).silk_mode.maxBits < (*st).silk_mode.bitRate * frame_size / (*st).Fs { + (*st).silk_mode.maxBits + } else { + (*st).silk_mode.bitRate * frame_size / (*st).Fs + }; + } + } else if (*st).mode == MODE_HYBRID { + let maxBitRate: i32 = compute_silk_rate_for_hybrid( + (*st).silk_mode.maxBits * (*st).Fs / frame_size, + curr_bandwidth, + ((*st).Fs == 50 * frame_size) as i32, + (*st).use_vbr, + (*st).silk_mode.LBRR_coded, + (*st).stream_channels, + ); + (*st).silk_mode.maxBits = maxBitRate * frame_size / (*st).Fs; + } + if prefill != 0 { + let mut zero: i32 = 0; + let mut prefill_offset: i32 = 0; + prefill_offset = + (*st).channels * ((*st).encoder_buffer - (*st).delay_compensation - (*st).Fs / 400); + gain_fade( + ((*st).delay_buffer) + .as_mut_ptr() + .offset(prefill_offset as isize), + ((*st).delay_buffer) + .as_mut_ptr() + .offset(prefill_offset as isize), + 0 as opus_val16, + Q15ONE, + (*celt_mode).overlap, + (*st).Fs / 400, + (*st).channels, + (*celt_mode).window, + (*st).Fs, + ); + memset( + ((*st).delay_buffer).as_mut_ptr() as *mut core::ffi::c_void, + 0, + (prefill_offset as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + i = 0; + while i < (*st).encoder_buffer * (*st).channels { + *pcm_silk.as_mut_ptr().offset(i as isize) = + FLOAT2INT16((*st).delay_buffer[i as usize]); + i += 1; + } + silk_Encode( + silk_enc, + &mut (*st).silk_mode, + pcm_silk.as_mut_ptr(), + (*st).encoder_buffer, + None, + &mut zero, + prefill, + activity, + ); + (*st).silk_mode.opusCanSwitch = 0; + } + i = 0; + while i < frame_size * (*st).channels { + *pcm_silk.as_mut_ptr().offset(i as isize) = FLOAT2INT16( + *pcm_buf + .as_mut_ptr() + .offset((total_buffer * (*st).channels + i) as isize), + ); + i += 1; + } + ret = silk_Encode( + silk_enc, + &mut (*st).silk_mode, + pcm_silk.as_mut_ptr(), + frame_size, + Some(&mut enc), + &mut nBytes, + 0, + activity, + ); + if ret != 0 { + return OPUS_INTERNAL_ERROR; + } + if (*st).mode == MODE_SILK_ONLY { + if (*st).silk_mode.internalSampleRate == 8000 { + curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } else if (*st).silk_mode.internalSampleRate == 12000 { + curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + } else if (*st).silk_mode.internalSampleRate == 16000 { + curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + } else { + assert!((*st).silk_mode.internalSampleRate == 16000) + }; + (*st).silk_mode.opusCanSwitch = + ((*st).silk_mode.switchReady != 0 && (*st).nonfinal_frame == 0) as i32; + if nBytes == 0 { + (*st).rangeFinal = 0; + *data.offset(-1 as isize) = gen_toc( + (*st).mode, + (*st).Fs / frame_size, + curr_bandwidth, + (*st).stream_channels, + ); + return 1; + } + if (*st).silk_mode.opusCanSwitch != 0 { + redundancy_bytes = compute_redundancy_bytes( + max_data_bytes, + (*st).bitrate_bps, + frame_rate, + (*st).stream_channels, + ); + redundancy = (redundancy_bytes != 0) as i32; + celt_to_silk = 0; + (*st).silk_bw_switch = 1; + } + } + let mut endband: i32 = 21; + match curr_bandwidth { + OPUS_BANDWIDTH_NARROWBAND => { + endband = 13; + } + OPUS_BANDWIDTH_MEDIUMBAND | OPUS_BANDWIDTH_WIDEBAND => { + endband = 17; + } + OPUS_BANDWIDTH_SUPERWIDEBAND => { + endband = 19; + } + OPUS_BANDWIDTH_FULLBAND => { + endband = 21; + } + _ => {} + } + opus_custom_encoder_ctl!(celt_enc, CELT_SET_END_BAND_REQUEST, endband); + opus_custom_encoder_ctl!(celt_enc, CELT_SET_CHANNELS_REQUEST, (*st).stream_channels); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_BITRATE_REQUEST, -1); + if (*st).mode != MODE_SILK_ONLY { + let mut celt_pred: opus_val32 = 2 as opus_val32; + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_VBR_REQUEST, 0); + if (*st).silk_mode.reducedDependency != 0 { + celt_pred = 0 as opus_val32; + } + opus_custom_encoder_ctl!(celt_enc, CELT_SET_PREDICTION_REQUEST, celt_pred as i32); + if (*st).mode == MODE_HYBRID { + if (*st).use_vbr != 0 { + opus_custom_encoder_ctl!( + celt_enc, + OPUS_SET_BITRATE_REQUEST, + (*st).bitrate_bps - (*st).silk_mode.bitRate, + ); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_VBR_CONSTRAINT_REQUEST, 0,); + } + } else if (*st).use_vbr != 0 { + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_VBR_REQUEST, 1); + opus_custom_encoder_ctl!( + celt_enc, + OPUS_SET_VBR_CONSTRAINT_REQUEST, + (*st).vbr_constraint, + ); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_BITRATE_REQUEST, (*st).bitrate_bps); + } + } + let vla_1 = ((*st).channels * (*st).Fs / 400) as usize; + let mut tmp_prefill: Vec = ::std::vec::from_elem(0., vla_1); + if (*st).mode != MODE_SILK_ONLY && (*st).mode != (*st).prev_mode && (*st).prev_mode > 0 { + memcpy( + tmp_prefill.as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*st).delay_buffer).as_mut_ptr().offset( + (((*st).encoder_buffer - total_buffer - (*st).Fs / 400) * (*st).channels) as isize, + ) as *mut opus_val16 as *const core::ffi::c_void, + (((*st).channels * (*st).Fs / 400) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * tmp_prefill.as_mut_ptr().offset_from( + &mut *((*st).delay_buffer).as_mut_ptr().offset( + (((*st).encoder_buffer - total_buffer - (*st).Fs / 400) + * (*st).channels) as isize, + ), + ) as i64) as u64, + ), + ); + } + if (*st).channels * ((*st).encoder_buffer - (frame_size + total_buffer)) > 0 { + memmove( + ((*st).delay_buffer).as_mut_ptr() as *mut core::ffi::c_void, + &mut *((*st).delay_buffer) + .as_mut_ptr() + .offset(((*st).channels * frame_size) as isize) as *mut opus_val16 + as *const core::ffi::c_void, + (((*st).channels * ((*st).encoder_buffer - frame_size - total_buffer)) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * ((*st).delay_buffer).as_mut_ptr().offset_from( + &mut *((*st).delay_buffer) + .as_mut_ptr() + .offset(((*st).channels * frame_size) as isize), + ) as i64) as u64, + ), + ); + memcpy( + &mut *((*st).delay_buffer).as_mut_ptr().offset( + ((*st).channels * ((*st).encoder_buffer - frame_size - total_buffer)) as isize, + ) as *mut opus_val16 as *mut core::ffi::c_void, + &mut *pcm_buf.as_mut_ptr().offset(0 as isize) as *mut opus_val16 + as *const core::ffi::c_void, + (((frame_size + total_buffer) * (*st).channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * (&mut *((*st).delay_buffer).as_mut_ptr().offset( + ((*st).channels * ((*st).encoder_buffer - frame_size - total_buffer)) + as isize, + ) as *mut opus_val16) + .offset_from(&mut *pcm_buf.as_mut_ptr().offset(0 as isize)) + as i64) as u64, + ), + ); + } else { + memcpy( + ((*st).delay_buffer).as_mut_ptr() as *mut core::ffi::c_void, + &mut *pcm_buf.as_mut_ptr().offset( + ((frame_size + total_buffer - (*st).encoder_buffer) * (*st).channels) as isize, + ) as *mut opus_val16 as *const core::ffi::c_void, + (((*st).encoder_buffer * (*st).channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * ((*st).delay_buffer).as_mut_ptr().offset_from( + &mut *pcm_buf.as_mut_ptr().offset( + ((frame_size + total_buffer - (*st).encoder_buffer) * (*st).channels) + as isize, + ), + ) as i64) as u64, + ), + ); + } + if (*st).prev_HB_gain < Q15ONE || HB_gain < Q15ONE { + gain_fade( + pcm_buf.as_mut_ptr(), + pcm_buf.as_mut_ptr(), + (*st).prev_HB_gain, + HB_gain, + (*celt_mode).overlap, + frame_size, + (*st).channels, + (*celt_mode).window, + (*st).Fs, + ); + } + (*st).prev_HB_gain = HB_gain; + if (*st).mode != MODE_HYBRID || (*st).stream_channels == 1 { + if equiv_rate > 32000 { + (*st).silk_mode.stereoWidth_Q14 = 16384; + } else if equiv_rate < 16000 { + (*st).silk_mode.stereoWidth_Q14 = 0; + } else { + (*st).silk_mode.stereoWidth_Q14 = + 16384 - 2048 * (32000 - equiv_rate) / (equiv_rate - 14000); + } + } + if ((*st).energy_masking).is_null() && (*st).channels == 2 { + if ((*st).hybrid_stereo_width_Q14 as i32) < (1) << 14 + || (*st).silk_mode.stereoWidth_Q14 < (1) << 14 + { + let mut g1: opus_val16 = 0.; + let mut g2: opus_val16 = 0.; + g1 = (*st).hybrid_stereo_width_Q14 as opus_val16; + g2 = (*st).silk_mode.stereoWidth_Q14 as opus_val16; + g1 *= 1.0f32 / 16384 as f32; + g2 *= 1.0f32 / 16384 as f32; + stereo_fade( + pcm_buf.as_mut_ptr(), + pcm_buf.as_mut_ptr(), + g1, + g2, + (*celt_mode).overlap, + frame_size, + (*st).channels, + (*celt_mode).window, + (*st).Fs, + ); + (*st).hybrid_stereo_width_Q14 = (*st).silk_mode.stereoWidth_Q14 as i16; + } + } + if (*st).mode != MODE_CELT_ONLY + && ec_tell(&mut enc) + 17 + 20 * ((*st).mode == MODE_HYBRID) as i32 + <= 8 * (max_data_bytes - 1) + { + if (*st).mode == MODE_HYBRID { + ec_enc_bit_logp(&mut enc, redundancy, 12); + } + if redundancy != 0 { + let mut max_redundancy: i32 = 0; + ec_enc_bit_logp(&mut enc, celt_to_silk, 1); + if (*st).mode == MODE_HYBRID { + max_redundancy = max_data_bytes - 1 - (ec_tell(&mut enc) + 8 + 3 + 7 >> 3); + } else { + max_redundancy = max_data_bytes - 1 - (ec_tell(&mut enc) + 7 >> 3); + } + redundancy_bytes = if max_redundancy < redundancy_bytes { + max_redundancy + } else { + redundancy_bytes + }; + redundancy_bytes = if (257) + < (if 2 > redundancy_bytes { + 2 + } else { + redundancy_bytes + }) { + 257 + } else if 2 > redundancy_bytes { + 2 + } else { + redundancy_bytes + }; + if (*st).mode == MODE_HYBRID { + ec_enc_uint(&mut enc, (redundancy_bytes - 2) as u32, 256); + } + } + } else { + redundancy = 0; + } + if redundancy == 0 { + (*st).silk_bw_switch = 0; + redundancy_bytes = 0; + } + if (*st).mode != MODE_CELT_ONLY { + start_band = 17; + } + if (*st).mode == MODE_SILK_ONLY { + ret = ec_tell(&mut enc) + 7 >> 3; + ec_enc_done(&mut enc); + nb_compr_bytes = ret; + } else { + nb_compr_bytes = max_data_bytes - 1 - redundancy_bytes; + ec_enc_shrink(&mut enc, nb_compr_bytes as u32); + } + if redundancy != 0 || (*st).mode != MODE_SILK_ONLY { + opus_custom_encoder_ctl!(celt_enc, CELT_SET_ANALYSIS_REQUEST, &mut analysis_info); + } + if (*st).mode == MODE_HYBRID { + let mut info: SILKInfo = SILKInfo { + signalType: 0, + offset: 0, + }; + info.signalType = (*st).silk_mode.signalType; + info.offset = (*st).silk_mode.offset; + opus_custom_encoder_ctl!(celt_enc, CELT_SET_SILK_INFO_REQUEST, &mut info); + } + if redundancy != 0 && celt_to_silk != 0 { + let mut err: i32 = 0; + opus_custom_encoder_ctl!(celt_enc, CELT_SET_START_BAND_REQUEST, 0); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_VBR_REQUEST, 0); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_BITRATE_REQUEST, -1); + err = celt_encode_with_ec( + celt_enc, + pcm_buf.as_mut_ptr(), + (*st).Fs / 200, + data.offset(nb_compr_bytes as isize), + redundancy_bytes, + None, + ); + if err < 0 { + return OPUS_INTERNAL_ERROR; + } + opus_custom_encoder_ctl!(celt_enc, OPUS_GET_FINAL_RANGE_REQUEST, &mut redundant_rng); + opus_custom_encoder_ctl!(celt_enc, OPUS_RESET_STATE); + } + opus_custom_encoder_ctl!(celt_enc, CELT_SET_START_BAND_REQUEST, start_band); + if (*st).mode != MODE_SILK_ONLY { + if (*st).mode != (*st).prev_mode && (*st).prev_mode > 0 { + let mut dummy_0: [u8; 2] = [0; 2]; + opus_custom_encoder_ctl!(celt_enc, OPUS_RESET_STATE); + celt_encode_with_ec( + celt_enc, + tmp_prefill.as_mut_ptr(), + (*st).Fs / 400, + dummy_0.as_mut_ptr(), + 2, + None, + ); + opus_custom_encoder_ctl!(celt_enc, CELT_SET_PREDICTION_REQUEST, 0); + } + if ec_tell(&mut enc) <= 8 * nb_compr_bytes { + if redundancy != 0 + && celt_to_silk != 0 + && (*st).mode == MODE_HYBRID + && (*st).use_vbr != 0 + { + opus_custom_encoder_ctl!( + celt_enc, + OPUS_SET_BITRATE_REQUEST, + (*st).bitrate_bps - (*st).silk_mode.bitRate, + ); + } + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_VBR_REQUEST, (*st).use_vbr); + ret = celt_encode_with_ec( + celt_enc, + pcm_buf.as_mut_ptr(), + frame_size, + NULL as *mut u8, + nb_compr_bytes, + Some(&mut enc), + ); + if ret < 0 { + return OPUS_INTERNAL_ERROR; + } + if redundancy != 0 + && celt_to_silk != 0 + && (*st).mode == MODE_HYBRID + && (*st).use_vbr != 0 + { + memmove( + data.offset(ret as isize) as *mut core::ffi::c_void, + data.offset(nb_compr_bytes as isize) as *const core::ffi::c_void, + (redundancy_bytes as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * data + .offset(ret as isize) + .offset_from(data.offset(nb_compr_bytes as isize)) + as i64) as u64, + ), + ); + nb_compr_bytes = nb_compr_bytes + redundancy_bytes; + } + } + } + if redundancy != 0 && celt_to_silk == 0 { + let mut err_0: i32 = 0; + let mut dummy_1: [u8; 2] = [0; 2]; + let mut N2: i32 = 0; + let mut N4: i32 = 0; + N2 = (*st).Fs / 200; + N4 = (*st).Fs / 400; + opus_custom_encoder_ctl!(celt_enc, OPUS_RESET_STATE); + opus_custom_encoder_ctl!(celt_enc, CELT_SET_START_BAND_REQUEST, 0); + opus_custom_encoder_ctl!(celt_enc, CELT_SET_PREDICTION_REQUEST, 0); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_VBR_REQUEST, 0); + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_BITRATE_REQUEST, -1); + if (*st).mode == MODE_HYBRID { + nb_compr_bytes = ret; + ec_enc_shrink(&mut enc, nb_compr_bytes as u32); + } + celt_encode_with_ec( + celt_enc, + pcm_buf + .as_mut_ptr() + .offset(((*st).channels * (frame_size - N2 - N4)) as isize), + N4, + dummy_1.as_mut_ptr(), + 2, + None, + ); + err_0 = celt_encode_with_ec( + celt_enc, + pcm_buf + .as_mut_ptr() + .offset(((*st).channels * (frame_size - N2)) as isize), + N2, + data.offset(nb_compr_bytes as isize), + redundancy_bytes, + None, + ); + if err_0 < 0 { + return OPUS_INTERNAL_ERROR; + } + opus_custom_encoder_ctl!(celt_enc, OPUS_GET_FINAL_RANGE_REQUEST, &mut redundant_rng); + } + data = data.offset(-1); + *data.offset(0 as isize) = gen_toc( + (*st).mode, + (*st).Fs / frame_size, + curr_bandwidth, + (*st).stream_channels, + ); + (*st).rangeFinal = enc.rng ^ redundant_rng; + if to_celt != 0 { + (*st).prev_mode = MODE_CELT_ONLY; + } else { + (*st).prev_mode = (*st).mode; + } + (*st).prev_channels = (*st).stream_channels; + (*st).prev_framesize = frame_size; + (*st).first = 0; + if (*st).use_dtx != 0 && (analysis_info.valid != 0 || is_silence != 0) { + if decide_dtx_mode( + analysis_info.activity_probability, + &mut (*st).nb_no_activity_frames, + (*st).peak_signal_energy, + pcm, + frame_size, + (*st).channels, + is_silence, + (*st).arch, + ) != 0 + { + (*st).rangeFinal = 0; + *data.offset(0 as isize) = gen_toc( + (*st).mode, + (*st).Fs / frame_size, + curr_bandwidth, + (*st).stream_channels, + ); + return 1; + } + } else { + (*st).nb_no_activity_frames = 0; + } + if ec_tell(&mut enc) > (max_data_bytes - 1) * 8 { + if max_data_bytes < 2 { + return OPUS_BUFFER_TOO_SMALL; + } + *data.offset(1 as isize) = 0; + ret = 1; + (*st).rangeFinal = 0; + } else if (*st).mode == MODE_SILK_ONLY && redundancy == 0 { + while ret > 2 && *data.offset(ret as isize) as i32 == 0 { + ret -= 1; + } + } + ret += 1 + redundancy_bytes; + if (*st).use_vbr == 0 { + if opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK { + return OPUS_INTERNAL_ERROR; + } + ret = max_data_bytes; + } + return ret; +} +pub unsafe fn opus_encode( + st: *mut OpusEncoder, + pcm: *const i16, + analysis_frame_size: i32, + data: *mut u8, + max_data_bytes: i32, +) -> i32 { + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut frame_size: i32 = 0; + frame_size = frame_size_select(analysis_frame_size, (*st).variable_duration, (*st).Fs); + if frame_size <= 0 { + return OPUS_BAD_ARG; + } + let vla = (frame_size * (*st).channels) as usize; + let mut in_0: Vec = ::std::vec::from_elem(0., vla); + i = 0; + while i < frame_size * (*st).channels { + *in_0.as_mut_ptr().offset(i as isize) = + 1.0f32 / 32768 as f32 * *pcm.offset(i as isize) as i32 as f32; + i += 1; + } + ret = opus_encode_native( + st, + in_0.as_mut_ptr(), + frame_size, + data, + max_data_bytes, + 16, + pcm as *const core::ffi::c_void, + analysis_frame_size, + 0, + -(2), + (*st).channels, + Some( + downmix_int + as unsafe fn( + *const core::ffi::c_void, + *mut opus_val32, + i32, + i32, + i32, + i32, + i32, + ) -> (), + ), + 0, + ); + return ret; +} +pub unsafe fn opus_encode_float( + st: *mut OpusEncoder, + pcm: *const f32, + analysis_frame_size: i32, + data: *mut u8, + out_data_bytes: i32, +) -> i32 { + let mut frame_size: i32 = 0; + frame_size = frame_size_select(analysis_frame_size, (*st).variable_duration, (*st).Fs); + return opus_encode_native( + st, + pcm, + frame_size, + data, + out_data_bytes, + 24, + pcm as *const core::ffi::c_void, + analysis_frame_size, + 0, + -(2), + (*st).channels, + Some( + downmix_float + as unsafe fn( + *const core::ffi::c_void, + *mut opus_val32, + i32, + i32, + i32, + i32, + i32, + ) -> (), + ), + 1, + ); +} +pub unsafe fn opus_encoder_ctl_impl(st: *mut OpusEncoder, request: i32, args: VarArgs) -> i32 { + let mut current_block: u64; + let mut ret: i32 = 0; + let mut celt_enc: *mut OpusCustomEncoder = 0 as *mut OpusCustomEncoder; + ret = OPUS_OK; + + let mut ap = args; + + celt_enc = (st as *mut i8).offset((*st).celt_enc_offset as isize) as *mut OpusCustomEncoder; + match request { + OPUS_SET_APPLICATION_REQUEST => { + let value: i32 = ap.arg::(); + if value != OPUS_APPLICATION_VOIP + && value != OPUS_APPLICATION_AUDIO + && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY + || (*st).first == 0 && (*st).application != value + { + ret = OPUS_BAD_ARG; + } else { + (*st).application = value; + (*st).analysis.application = value; + } + current_block = 16167632229894708628; + } + OPUS_GET_APPLICATION_REQUEST => { + let value_0 = ap.arg::<&mut i32>(); + *value_0 = (*st).application; + current_block = 16167632229894708628; + } + OPUS_SET_BITRATE_REQUEST => { + let mut value_1: i32 = ap.arg::(); + if value_1 != OPUS_AUTO && value_1 != OPUS_BITRATE_MAX { + if value_1 <= 0 { + current_block = 12343738388509029619; + } else { + if value_1 <= 500 { + value_1 = 500; + } else if value_1 > 300000 * (*st).channels { + value_1 = 300000 * (*st).channels; + } + current_block = 6057473163062296781; + } + } else { + current_block = 6057473163062296781; + } + match current_block { + 12343738388509029619 => {} + _ => { + (*st).user_bitrate_bps = value_1; + current_block = 16167632229894708628; + } + } + } + OPUS_GET_BITRATE_REQUEST => { + let value_2 = ap.arg::<&mut i32>(); + *value_2 = user_bitrate_to_bitrate(st, (*st).prev_framesize, 1276); + current_block = 16167632229894708628; + } + OPUS_SET_FORCE_CHANNELS_REQUEST => { + let value_3: i32 = ap.arg::(); + if (value_3 < 1 || value_3 > (*st).channels) && value_3 != OPUS_AUTO { + current_block = 12343738388509029619; + } else { + (*st).force_channels = value_3; + current_block = 16167632229894708628; + } + } + OPUS_GET_FORCE_CHANNELS_REQUEST => { + let value_4 = ap.arg::<&mut i32>(); + *value_4 = (*st).force_channels; + current_block = 16167632229894708628; + } + OPUS_SET_MAX_BANDWIDTH_REQUEST => { + let value_5: i32 = ap.arg::(); + if value_5 < OPUS_BANDWIDTH_NARROWBAND || value_5 > OPUS_BANDWIDTH_FULLBAND { + current_block = 12343738388509029619; + } else { + (*st).max_bandwidth = value_5; + if (*st).max_bandwidth == OPUS_BANDWIDTH_NARROWBAND { + (*st).silk_mode.maxInternalSampleRate = 8000; + } else if (*st).max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + (*st).silk_mode.maxInternalSampleRate = 12000; + } else { + (*st).silk_mode.maxInternalSampleRate = 16000; + } + current_block = 16167632229894708628; + } + } + OPUS_GET_MAX_BANDWIDTH_REQUEST => { + let value_6 = ap.arg::<&mut i32>(); + *value_6 = (*st).max_bandwidth; + current_block = 16167632229894708628; + } + OPUS_SET_BANDWIDTH_REQUEST => { + let value_7: i32 = ap.arg::(); + if (value_7 < OPUS_BANDWIDTH_NARROWBAND || value_7 > OPUS_BANDWIDTH_FULLBAND) + && value_7 != OPUS_AUTO + { + current_block = 12343738388509029619; + } else { + (*st).user_bandwidth = value_7; + if (*st).user_bandwidth == OPUS_BANDWIDTH_NARROWBAND { + (*st).silk_mode.maxInternalSampleRate = 8000; + } else if (*st).user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND { + (*st).silk_mode.maxInternalSampleRate = 12000; + } else { + (*st).silk_mode.maxInternalSampleRate = 16000; + } + current_block = 16167632229894708628; + } + } + OPUS_GET_BANDWIDTH_REQUEST => { + let value_8 = ap.arg::<&mut i32>(); + *value_8 = (*st).bandwidth; + current_block = 16167632229894708628; + } + OPUS_SET_DTX_REQUEST => { + let value_9: i32 = ap.arg::(); + if value_9 < 0 || value_9 > 1 { + current_block = 12343738388509029619; + } else { + (*st).use_dtx = value_9; + current_block = 16167632229894708628; + } + } + OPUS_GET_DTX_REQUEST => { + let value_10 = ap.arg::<&mut i32>(); + *value_10 = (*st).use_dtx; + current_block = 16167632229894708628; + } + OPUS_SET_COMPLEXITY_REQUEST => { + let value_11: i32 = ap.arg::(); + if value_11 < 0 || value_11 > 10 { + current_block = 12343738388509029619; + } else { + (*st).silk_mode.complexity = value_11; + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_COMPLEXITY_REQUEST, value_11); + current_block = 16167632229894708628; + } + } + OPUS_GET_COMPLEXITY_REQUEST => { + let value_12 = ap.arg::<&mut i32>(); + *value_12 = (*st).silk_mode.complexity; + current_block = 16167632229894708628; + } + OPUS_SET_INBAND_FEC_REQUEST => { + let value_13: i32 = ap.arg::(); + if value_13 < 0 || value_13 > 1 { + current_block = 12343738388509029619; + } else { + (*st).silk_mode.useInBandFEC = value_13; + current_block = 16167632229894708628; + } + } + OPUS_GET_INBAND_FEC_REQUEST => { + let value_14 = ap.arg::<&mut i32>(); + *value_14 = (*st).silk_mode.useInBandFEC; + current_block = 16167632229894708628; + } + OPUS_SET_PACKET_LOSS_PERC_REQUEST => { + let value_15: i32 = ap.arg::(); + if value_15 < 0 || value_15 > 100 { + current_block = 12343738388509029619; + } else { + (*st).silk_mode.packetLossPercentage = value_15; + opus_custom_encoder_ctl!(celt_enc, OPUS_SET_PACKET_LOSS_PERC_REQUEST, value_15); + current_block = 16167632229894708628; + } + } + OPUS_GET_PACKET_LOSS_PERC_REQUEST => { + let value_16 = ap.arg::<&mut i32>(); + *value_16 = (*st).silk_mode.packetLossPercentage; + current_block = 16167632229894708628; + } + OPUS_SET_VBR_REQUEST => { + let value_17: i32 = ap.arg::(); + if value_17 < 0 || value_17 > 1 { + current_block = 12343738388509029619; + } else { + (*st).use_vbr = value_17; + (*st).silk_mode.useCBR = 1 - value_17; + current_block = 16167632229894708628; + } + } + OPUS_GET_VBR_REQUEST => { + let value_18 = ap.arg::<&mut i32>(); + *value_18 = (*st).use_vbr; + current_block = 16167632229894708628; + } + OPUS_SET_VOICE_RATIO_REQUEST => { + let value_19: i32 = ap.arg::(); + if value_19 < -1 || value_19 > 100 { + current_block = 12343738388509029619; + } else { + (*st).voice_ratio = value_19; + current_block = 16167632229894708628; + } + } + OPUS_GET_VOICE_RATIO_REQUEST => { + let value_20 = ap.arg::<&mut i32>(); + *value_20 = (*st).voice_ratio; + current_block = 16167632229894708628; + } + OPUS_SET_VBR_CONSTRAINT_REQUEST => { + let value_21: i32 = ap.arg::(); + if value_21 < 0 || value_21 > 1 { + current_block = 12343738388509029619; + } else { + (*st).vbr_constraint = value_21; + current_block = 16167632229894708628; + } + } + OPUS_GET_VBR_CONSTRAINT_REQUEST => { + let value_22 = ap.arg::<&mut i32>(); + *value_22 = (*st).vbr_constraint; + current_block = 16167632229894708628; + } + OPUS_SET_SIGNAL_REQUEST => { + let value_23: i32 = ap.arg::(); + if value_23 != OPUS_AUTO + && value_23 != OPUS_SIGNAL_VOICE + && value_23 != OPUS_SIGNAL_MUSIC + { + current_block = 12343738388509029619; + } else { + (*st).signal_type = value_23; + current_block = 16167632229894708628; + } + } + OPUS_GET_SIGNAL_REQUEST => { + let value_24 = ap.arg::<&mut i32>(); + *value_24 = (*st).signal_type; + current_block = 16167632229894708628; + } + OPUS_GET_LOOKAHEAD_REQUEST => { + let value_25 = ap.arg::<&mut i32>(); + *value_25 = (*st).Fs / 400; + if (*st).application != OPUS_APPLICATION_RESTRICTED_LOWDELAY { + *value_25 += (*st).delay_compensation; + } + current_block = 16167632229894708628; + } + OPUS_GET_SAMPLE_RATE_REQUEST => { + let value_26 = ap.arg::<&mut i32>(); + *value_26 = (*st).Fs; + current_block = 16167632229894708628; + } + OPUS_GET_FINAL_RANGE_REQUEST => { + let value_27 = ap.arg::<&mut u32>(); + *value_27 = (*st).rangeFinal; + current_block = 16167632229894708628; + } + OPUS_SET_LSB_DEPTH_REQUEST => { + let value_28: i32 = ap.arg::(); + if value_28 < 8 || value_28 > 24 { + current_block = 12343738388509029619; + } else { + (*st).lsb_depth = value_28; + current_block = 16167632229894708628; + } + } + OPUS_GET_LSB_DEPTH_REQUEST => { + let value_29 = ap.arg::<&mut i32>(); + *value_29 = (*st).lsb_depth; + current_block = 16167632229894708628; + } + OPUS_SET_EXPERT_FRAME_DURATION_REQUEST => { + let value_30: i32 = ap.arg::(); + if value_30 != OPUS_FRAMESIZE_ARG + && value_30 != OPUS_FRAMESIZE_2_5_MS + && value_30 != OPUS_FRAMESIZE_5_MS + && value_30 != OPUS_FRAMESIZE_10_MS + && value_30 != OPUS_FRAMESIZE_20_MS + && value_30 != OPUS_FRAMESIZE_40_MS + && value_30 != OPUS_FRAMESIZE_60_MS + && value_30 != OPUS_FRAMESIZE_80_MS + && value_30 != OPUS_FRAMESIZE_100_MS + && value_30 != OPUS_FRAMESIZE_120_MS + { + current_block = 12343738388509029619; + } else { + (*st).variable_duration = value_30; + current_block = 16167632229894708628; + } + } + OPUS_GET_EXPERT_FRAME_DURATION_REQUEST => { + let value_31 = ap.arg::<&mut i32>(); + *value_31 = (*st).variable_duration; + current_block = 16167632229894708628; + } + OPUS_SET_PREDICTION_DISABLED_REQUEST => { + let value_32: i32 = ap.arg::(); + if value_32 > 1 || value_32 < 0 { + current_block = 12343738388509029619; + } else { + (*st).silk_mode.reducedDependency = value_32; + current_block = 16167632229894708628; + } + } + OPUS_GET_PREDICTION_DISABLED_REQUEST => { + let value_33 = ap.arg::<&mut i32>(); + *value_33 = (*st).silk_mode.reducedDependency; + current_block = 16167632229894708628; + } + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_34: i32 = ap.arg::(); + if value_34 < 0 || value_34 > 1 { + current_block = 12343738388509029619; + } else { + opus_custom_encoder_ctl!( + celt_enc, + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, + value_34, + ); + current_block = 16167632229894708628; + } + } + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => { + let value_35 = ap.arg::<&mut i32>(); + opus_custom_encoder_ctl!( + celt_enc, + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, + value_35 + ); + current_block = 16167632229894708628; + } + OPUS_RESET_STATE => { + let mut silk_enc: *mut core::ffi::c_void = 0 as *mut core::ffi::c_void; + let mut dummy: silk_EncControlStruct = silk_EncControlStruct { + nChannelsAPI: 0, + nChannelsInternal: 0, + API_sampleRate: 0, + maxInternalSampleRate: 0, + minInternalSampleRate: 0, + desiredInternalSampleRate: 0, + payloadSize_ms: 0, + bitRate: 0, + packetLossPercentage: 0, + complexity: 0, + useInBandFEC: 0, + LBRR_coded: 0, + useDTX: 0, + useCBR: 0, + maxBits: 0, + toMono: 0, + opusCanSwitch: 0, + reducedDependency: 0, + internalSampleRate: 0, + allowBandwidthSwitch: 0, + inWBmodeWithoutVariableLP: 0, + stereoWidth_Q14: 0, + switchReady: 0, + signalType: 0, + offset: 0, + }; + let mut start: *mut i8 = 0 as *mut i8; + silk_enc = + (st as *mut i8).offset((*st).silk_enc_offset as isize) as *mut core::ffi::c_void; + tonality_analysis_reset(&mut (*st).analysis); + start = &mut (*st).stream_channels as *mut i32 as *mut i8; + memset( + start as *mut core::ffi::c_void, + 0, + (::core::mem::size_of::() as u64) + .wrapping_sub(start.offset_from(st as *mut i8) as i64 as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + opus_custom_encoder_ctl!(celt_enc, OPUS_RESET_STATE); + silk_InitEncoder(silk_enc, (*st).arch, &mut dummy); + (*st).stream_channels = (*st).channels; + (*st).hybrid_stereo_width_Q14 = ((1) << 14) as i16; + (*st).prev_HB_gain = Q15ONE; + (*st).first = 1; + (*st).mode = MODE_HYBRID; + (*st).bandwidth = OPUS_BANDWIDTH_FULLBAND; + (*st).variable_HP_smth2_Q15 = ((silk_lin2log(60) as u32) << 8) as i32; + current_block = 16167632229894708628; + } + OPUS_SET_FORCE_MODE_REQUEST => { + let value_36: i32 = ap.arg::(); + if (value_36 < MODE_SILK_ONLY || value_36 > MODE_CELT_ONLY) && value_36 != OPUS_AUTO { + current_block = 12343738388509029619; + } else { + (*st).user_forced_mode = value_36; + current_block = 16167632229894708628; + } + } + OPUS_SET_LFE_REQUEST => { + let value_37: i32 = ap.arg::(); + (*st).lfe = value_37; + ret = opus_custom_encoder_ctl!(celt_enc, OPUS_SET_LFE_REQUEST, value_37); + current_block = 16167632229894708628; + } + OPUS_SET_ENERGY_MASK_REQUEST => { + let value_38: *mut opus_val16 = ap.arg::<*mut opus_val16>(); + (*st).energy_masking = value_38; + ret = opus_custom_encoder_ctl!( + celt_enc, + OPUS_SET_ENERGY_MASK_REQUEST, + value_38.offset(value_38.offset_from(value_38) as i64 as isize), + ); + current_block = 16167632229894708628; + } + OPUS_GET_IN_DTX_REQUEST => { + let value_39: &mut i32 = ap.arg::<&mut i32>(); + if (*st).silk_mode.useDTX != 0 + && ((*st).prev_mode == MODE_SILK_ONLY || (*st).prev_mode == MODE_HYBRID) + { + let mut n: i32 = 0; + let silk_enc_0: *mut core::ffi::c_void = (st as *mut i8) + .offset((*st).silk_enc_offset as isize) + as *mut core::ffi::c_void; + *value_39 = 1; + n = 0; + while n < (*st).silk_mode.nChannelsInternal { + *value_39 = (*value_39 != 0 + && (*(silk_enc_0 as *mut silk_encoder)).state_Fxx[n as usize] + .sCmn + .noSpeechCounter + >= NB_SPEECH_FRAMES_BEFORE_DTX) as i32; + n += 1; + } + } else if (*st).use_dtx != 0 { + *value_39 = ((*st).nb_no_activity_frames >= NB_SPEECH_FRAMES_BEFORE_DTX) as i32; + } else { + *value_39 = 0; + } + current_block = 16167632229894708628; + } + CELT_GET_MODE_REQUEST => { + let value_40: &mut *const OpusCustomMode = ap.arg::<&mut *const OpusCustomMode>(); + ret = opus_custom_encoder_ctl!(celt_enc, CELT_GET_MODE_REQUEST, value_40); + current_block = 16167632229894708628; + } + _ => { + ret = OPUS_UNIMPLEMENTED; + current_block = 16167632229894708628; + } + } + match current_block { + 12343738388509029619 => return OPUS_BAD_ARG, + _ => return ret, + }; +} +#[macro_export] +macro_rules! opus_encoder_ctl { + ($st:expr, $request:expr, $($args:expr),*) => { + $crate::opus_encoder_ctl_impl($st, $request, $crate::varargs!($($args),*)) + }; + ($st:expr, $request:expr, $($args:expr),*,) => { + opus_encoder_ctl!($st, $request, $($args),*) + }; + ($st:expr, $request:expr) => { + opus_encoder_ctl!($st, $request,) + }; +} +pub unsafe fn opus_encoder_destroy(st: *mut OpusEncoder) { + free(st as *mut core::ffi::c_void); +} diff --git a/vendor/unsafe-libopus/src/src/opus_multistream.rs b/vendor/unsafe-libopus/src/src/opus_multistream.rs new file mode 100644 index 00000000..4e3213fa --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_multistream.rs @@ -0,0 +1,59 @@ +#[derive(Copy, Clone)] +#[repr(C)] +pub struct ChannelLayout { + pub nb_channels: i32, + pub nb_streams: i32, + pub nb_coupled_streams: i32, + pub mapping: [u8; 256], +} +pub unsafe fn validate_layout(layout: *const ChannelLayout) -> i32 { + let mut i: i32 = 0; + let mut max_channel: i32 = 0; + max_channel = (*layout).nb_streams + (*layout).nb_coupled_streams; + if max_channel > 255 { + return 0; + } + i = 0; + while i < (*layout).nb_channels { + if (*layout).mapping[i as usize] as i32 >= max_channel + && (*layout).mapping[i as usize] as i32 != 255 + { + return 0; + } + i += 1; + } + return 1; +} +pub unsafe fn get_left_channel(layout: *const ChannelLayout, stream_id: i32, prev: i32) -> i32 { + let mut i: i32 = 0; + i = if prev < 0 { 0 } else { prev + 1 }; + while i < (*layout).nb_channels { + if (*layout).mapping[i as usize] as i32 == stream_id * 2 { + return i; + } + i += 1; + } + return -1; +} +pub unsafe fn get_right_channel(layout: *const ChannelLayout, stream_id: i32, prev: i32) -> i32 { + let mut i: i32 = 0; + i = if prev < 0 { 0 } else { prev + 1 }; + while i < (*layout).nb_channels { + if (*layout).mapping[i as usize] as i32 == stream_id * 2 + 1 { + return i; + } + i += 1; + } + return -1; +} +pub unsafe fn get_mono_channel(layout: *const ChannelLayout, stream_id: i32, prev: i32) -> i32 { + let mut i: i32 = 0; + i = if prev < 0 { 0 } else { prev + 1 }; + while i < (*layout).nb_channels { + if (*layout).mapping[i as usize] as i32 == stream_id + (*layout).nb_coupled_streams { + return i; + } + i += 1; + } + return -1; +} diff --git a/vendor/unsafe-libopus/src/src/opus_multistream_decoder.rs b/vendor/unsafe-libopus/src/src/opus_multistream_decoder.rs new file mode 100644 index 00000000..47eefc7f --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_multistream_decoder.rs @@ -0,0 +1,638 @@ +use crate::externs::{free, malloc}; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusMSDecoder { + pub layout: ChannelLayout, +} + +pub type opus_copy_channel_out_func = Option< + unsafe fn( + *mut core::ffi::c_void, + i32, + i32, + *const opus_val16, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), +>; + +pub mod arch_h { + pub type opus_val16 = f32; +} +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} +pub mod xmmintrin_h { + #[cfg(target_arch = "x86")] + pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; + #[cfg(target_arch = "x86_64")] + pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss}; +} +use self::arch_h::opus_val16; +pub use self::stddef_h::{size_t, NULL}; +use crate::celt::float_cast::FLOAT2INT16; +use crate::src::opus::opus_packet_parse_impl; +use crate::src::opus_decoder::opus_decode_native; +use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_BUFFER_TOO_SMALL, OPUS_GET_BANDWIDTH_REQUEST, + OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_GAIN_REQUEST, OPUS_GET_LAST_PACKET_DURATION_REQUEST, + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_INTERNAL_ERROR, + OPUS_INVALID_PACKET, OPUS_OK, OPUS_RESET_STATE, OPUS_SET_GAIN_REQUEST, + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_UNIMPLEMENTED, +}; +use crate::src::opus_multistream::{ + get_left_channel, get_mono_channel, get_right_channel, validate_layout, ChannelLayout, +}; +use crate::src::opus_private::align; +use crate::varargs::VarArgs; +use crate::{ + opus_decoder_ctl, opus_decoder_get_size, opus_decoder_init, opus_multistream_decoder_ctl, + opus_packet_get_nb_samples, OpusDecoder, +}; + +pub const OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: i32 = 5122; + +unsafe fn validate_ms_decoder(st: *mut OpusMSDecoder) { + validate_layout(&mut (*st).layout); +} +pub unsafe fn opus_multistream_decoder_get_size(nb_streams: i32, nb_coupled_streams: i32) -> i32 { + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + if nb_streams < 1 || nb_coupled_streams > nb_streams || nb_coupled_streams < 0 { + return 0; + } + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + return align(::core::mem::size_of::() as u64 as i32) + + nb_coupled_streams * align(coupled_size) + + (nb_streams - nb_coupled_streams) * align(mono_size); +} +pub unsafe fn opus_multistream_decoder_init( + st: *mut OpusMSDecoder, + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + mapping: *const u8, +) -> i32 { + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + if channels > 255 + || channels < 1 + || coupled_streams > streams + || streams < 1 + || coupled_streams < 0 + || streams > 255 - coupled_streams + { + return OPUS_BAD_ARG; + } + (*st).layout.nb_channels = channels; + (*st).layout.nb_streams = streams; + (*st).layout.nb_coupled_streams = coupled_streams; + i = 0; + while i < (*st).layout.nb_channels { + (*st).layout.mapping[i as usize] = *mapping.offset(i as isize); + i += 1; + } + if validate_layout(&mut (*st).layout) == 0 { + return OPUS_BAD_ARG; + } + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + i = 0; + while i < (*st).layout.nb_coupled_streams { + ret = opus_decoder_init(ptr as *mut OpusDecoder, Fs, 2); + if ret != OPUS_OK { + return ret; + } + ptr = ptr.offset(align(coupled_size) as isize); + i += 1; + } + while i < (*st).layout.nb_streams { + ret = opus_decoder_init(ptr as *mut OpusDecoder, Fs, 1); + if ret != OPUS_OK { + return ret; + } + ptr = ptr.offset(align(mono_size) as isize); + i += 1; + } + return OPUS_OK; +} +pub unsafe fn opus_multistream_decoder_create( + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + mapping: *const u8, + error: *mut i32, +) -> *mut OpusMSDecoder { + let mut ret: i32 = 0; + let mut st: *mut OpusMSDecoder = 0 as *mut OpusMSDecoder; + if channels > 255 + || channels < 1 + || coupled_streams > streams + || streams < 1 + || coupled_streams < 0 + || streams > 255 - coupled_streams + { + if !error.is_null() { + *error = OPUS_BAD_ARG; + } + return NULL as *mut OpusMSDecoder; + } + st = malloc(opus_multistream_decoder_get_size(streams, coupled_streams) as size_t) + as *mut OpusMSDecoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusMSDecoder; + } + ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); + if !error.is_null() { + *error = ret; + } + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusMSDecoder; + } + return st; +} +unsafe fn opus_multistream_packet_validate( + mut data: *const u8, + mut len: i32, + nb_streams: i32, + Fs: i32, +) -> i32 { + let mut s: i32 = 0; + let mut count: i32 = 0; + let mut toc: u8 = 0; + let mut size: [i16; 48] = [0; 48]; + let mut samples: i32 = 0; + let mut packet_offset: i32 = 0; + s = 0; + while s < nb_streams { + let mut tmp_samples: i32 = 0; + if len <= 0 { + return OPUS_INVALID_PACKET; + } + count = opus_packet_parse_impl( + data, + len, + (s != nb_streams - 1) as i32, + &mut toc, + NULL as *mut *const u8, + size.as_mut_ptr(), + NULL as *mut i32, + &mut packet_offset, + ); + if count < 0 { + return count; + } + tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs); + if s != 0 && samples != tmp_samples { + return OPUS_INVALID_PACKET; + } + samples = tmp_samples; + data = data.offset(packet_offset as isize); + len -= packet_offset; + s += 1; + } + return samples; +} +pub unsafe fn opus_multistream_decode_native( + st: *mut OpusMSDecoder, + mut data: *const u8, + mut len: i32, + pcm: *mut core::ffi::c_void, + copy_channel_out: opus_copy_channel_out_func, + mut frame_size: i32, + decode_fec: i32, + soft_clip: i32, + user_data: *mut core::ffi::c_void, +) -> i32 { + let mut Fs: i32 = 0; + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + let mut s: i32 = 0; + let mut c: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + let mut do_plc: i32 = 0; + validate_ms_decoder(st); + if frame_size <= 0 { + return OPUS_BAD_ARG; + } + assert!(opus_multistream_decoder_ctl!(st, 4029, &mut Fs) == 0); + frame_size = if frame_size < Fs / 25 * 3 { + frame_size + } else { + Fs / 25 * 3 + }; + let vla = (2 * frame_size) as usize; + let mut buf: Vec = ::std::vec::from_elem(0., vla); + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + if len == 0 { + do_plc = 1; + } + if len < 0 { + return OPUS_BAD_ARG; + } + if do_plc == 0 && len < 2 * (*st).layout.nb_streams - 1 { + return OPUS_INVALID_PACKET; + } + if do_plc == 0 { + let ret: i32 = opus_multistream_packet_validate(data, len, (*st).layout.nb_streams, Fs); + if ret < 0 { + return ret; + } else { + if ret > frame_size { + return OPUS_BUFFER_TOO_SMALL; + } + } + } + s = 0; + while s < (*st).layout.nb_streams { + let mut dec: *mut OpusDecoder = 0 as *mut OpusDecoder; + let mut packet_offset: i32 = 0; + let mut ret_0: i32 = 0; + dec = ptr as *mut OpusDecoder; + ptr = ptr.offset( + (if s < (*st).layout.nb_coupled_streams { + align(coupled_size) + } else { + align(mono_size) + }) as isize, + ); + if do_plc == 0 && len <= 0 { + return OPUS_INTERNAL_ERROR; + } + packet_offset = 0; + ret_0 = opus_decode_native( + dec, + data, + len, + buf.as_mut_ptr(), + frame_size, + decode_fec, + (s != (*st).layout.nb_streams - 1) as i32, + &mut packet_offset, + soft_clip, + ); + data = data.offset(packet_offset as isize); + len -= packet_offset; + if ret_0 <= 0 { + return ret_0; + } + frame_size = ret_0; + if s < (*st).layout.nb_coupled_streams { + let mut chan: i32 = 0; + let mut prev: i32 = 0; + prev = -1; + loop { + chan = get_left_channel(&mut (*st).layout, s, prev); + if !(chan != -1) { + break; + } + (Some(copy_channel_out.expect("non-null function pointer"))) + .expect("non-null function pointer")( + pcm, + (*st).layout.nb_channels, + chan, + buf.as_mut_ptr(), + 2, + frame_size, + user_data, + ); + prev = chan; + } + prev = -1; + loop { + chan = get_right_channel(&mut (*st).layout, s, prev); + if !(chan != -1) { + break; + } + (Some(copy_channel_out.expect("non-null function pointer"))) + .expect("non-null function pointer")( + pcm, + (*st).layout.nb_channels, + chan, + buf.as_mut_ptr().offset(1 as isize), + 2, + frame_size, + user_data, + ); + prev = chan; + } + } else { + let mut chan_0: i32 = 0; + let mut prev_0: i32 = 0; + prev_0 = -1; + loop { + chan_0 = get_mono_channel(&mut (*st).layout, s, prev_0); + if !(chan_0 != -1) { + break; + } + (Some(copy_channel_out.expect("non-null function pointer"))) + .expect("non-null function pointer")( + pcm, + (*st).layout.nb_channels, + chan_0, + buf.as_mut_ptr(), + 1, + frame_size, + user_data, + ); + prev_0 = chan_0; + } + } + s += 1; + } + c = 0; + while c < (*st).layout.nb_channels { + if (*st).layout.mapping[c as usize] as i32 == 255 { + (Some(copy_channel_out.expect("non-null function pointer"))) + .expect("non-null function pointer")( + pcm, + (*st).layout.nb_channels, + c, + NULL as *const opus_val16, + 0, + frame_size, + user_data, + ); + } + c += 1; + } + return frame_size; +} +unsafe fn opus_copy_channel_out_float( + dst: *mut core::ffi::c_void, + dst_stride: i32, + dst_channel: i32, + src: *const opus_val16, + src_stride: i32, + frame_size: i32, + _user_data: *mut core::ffi::c_void, +) { + let mut float_dst: *mut f32 = 0 as *mut f32; + let mut i: i32 = 0; + float_dst = dst as *mut f32; + if !src.is_null() { + i = 0; + while i < frame_size { + *float_dst.offset((i * dst_stride + dst_channel) as isize) = + *src.offset((i * src_stride) as isize); + i += 1; + } + } else { + i = 0; + while i < frame_size { + *float_dst.offset((i * dst_stride + dst_channel) as isize) = 0 as f32; + i += 1; + } + }; +} +unsafe fn opus_copy_channel_out_short( + dst: *mut core::ffi::c_void, + dst_stride: i32, + dst_channel: i32, + src: *const opus_val16, + src_stride: i32, + frame_size: i32, + _user_data: *mut core::ffi::c_void, +) { + let mut short_dst: *mut i16 = 0 as *mut i16; + let mut i: i32 = 0; + short_dst = dst as *mut i16; + if !src.is_null() { + i = 0; + while i < frame_size { + *short_dst.offset((i * dst_stride + dst_channel) as isize) = + FLOAT2INT16(*src.offset((i * src_stride) as isize)); + i += 1; + } + } else { + i = 0; + while i < frame_size { + *short_dst.offset((i * dst_stride + dst_channel) as isize) = 0; + i += 1; + } + }; +} +pub unsafe fn opus_multistream_decode( + st: *mut OpusMSDecoder, + data: *const u8, + len: i32, + pcm: *mut i16, + frame_size: i32, + decode_fec: i32, +) -> i32 { + return opus_multistream_decode_native( + st, + data, + len, + pcm as *mut core::ffi::c_void, + Some( + opus_copy_channel_out_short + as unsafe fn( + *mut core::ffi::c_void, + i32, + i32, + *const opus_val16, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + frame_size, + decode_fec, + 1, + NULL as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_multistream_decode_float( + st: *mut OpusMSDecoder, + data: *const u8, + len: i32, + pcm: *mut opus_val16, + frame_size: i32, + decode_fec: i32, +) -> i32 { + return opus_multistream_decode_native( + st, + data, + len, + pcm as *mut core::ffi::c_void, + Some( + opus_copy_channel_out_float + as unsafe fn( + *mut core::ffi::c_void, + i32, + i32, + *const opus_val16, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + frame_size, + decode_fec, + 0, + NULL as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_multistream_decoder_ctl_va_list( + st: *mut OpusMSDecoder, + request: i32, + mut ap: VarArgs, +) -> i32 { + let current_block: u64; + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + let mut ret: i32 = OPUS_OK; + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + match request { + OPUS_GET_BANDWIDTH_REQUEST + | OPUS_GET_SAMPLE_RATE_REQUEST + | OPUS_GET_GAIN_REQUEST + | OPUS_GET_LAST_PACKET_DURATION_REQUEST + | OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => { + let mut dec: *mut OpusDecoder = 0 as *mut OpusDecoder; + let value: &mut i32 = ap.arg::<&mut i32>(); + dec = ptr as *mut OpusDecoder; + ret = opus_decoder_ctl!(dec, request, value); + current_block = 7343950298149844727; + } + OPUS_GET_FINAL_RANGE_REQUEST => { + let mut s: i32 = 0; + let value_0 = ap.arg::<&mut u32>(); + let mut tmp: u32 = 0; + *value_0 = 0; + s = 0; + while s < (*st).layout.nb_streams { + let mut dec_0: *mut OpusDecoder = 0 as *mut OpusDecoder; + dec_0 = ptr as *mut OpusDecoder; + if s < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + ret = opus_decoder_ctl!(dec_0, request, &mut tmp); + if ret != OPUS_OK { + break; + } + *value_0 ^= tmp; + s += 1; + } + current_block = 7343950298149844727; + } + OPUS_RESET_STATE => { + let mut s_0: i32 = 0; + s_0 = 0; + while s_0 < (*st).layout.nb_streams { + let mut dec_1: *mut OpusDecoder = 0 as *mut OpusDecoder; + dec_1 = ptr as *mut OpusDecoder; + if s_0 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + ret = opus_decoder_ctl!(dec_1, OPUS_RESET_STATE); + if ret != OPUS_OK { + break; + } + s_0 += 1; + } + current_block = 7343950298149844727; + } + OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST => { + let mut s_1: i32 = 0; + let mut stream_id: i32 = 0; + let mut value_1: *mut *mut OpusDecoder = 0 as *mut *mut OpusDecoder; + stream_id = ap.arg::(); + if stream_id < 0 || stream_id >= (*st).layout.nb_streams { + current_block = 15933654591644784431; + } else { + value_1 = ap.arg::<&mut *mut OpusDecoder>(); + s_1 = 0; + while s_1 < stream_id { + if s_1 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + s_1 += 1; + } + *value_1 = ptr as *mut OpusDecoder; + current_block = 7343950298149844727; + } + } + OPUS_SET_GAIN_REQUEST | OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => { + let mut s_2: i32 = 0; + let value_2: i32 = ap.arg::(); + s_2 = 0; + while s_2 < (*st).layout.nb_streams { + let mut dec_2: *mut OpusDecoder = 0 as *mut OpusDecoder; + dec_2 = ptr as *mut OpusDecoder; + if s_2 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + ret = opus_decoder_ctl!(dec_2, request, value_2); + if ret != OPUS_OK { + break; + } + s_2 += 1; + } + current_block = 7343950298149844727; + } + _ => { + ret = OPUS_UNIMPLEMENTED; + current_block = 7343950298149844727; + } + } + match current_block { + 15933654591644784431 => return OPUS_BAD_ARG, + _ => return ret, + }; +} +pub unsafe fn opus_multistream_decoder_ctl_impl( + st: *mut OpusMSDecoder, + request: i32, + args: VarArgs, +) -> i32 { + let mut ret: i32 = 0; + ret = opus_multistream_decoder_ctl_va_list(st, request, args); + return ret; +} +#[macro_export] +macro_rules! opus_multistream_decoder_ctl { + ($st:expr, $request:expr, $($arg:expr),*) => { + $crate::opus_multistream_decoder_ctl_impl($st, $request, $crate::varargs!($($arg),*)) + }; + ($st:expr, $request:expr) => { + opus_multistream_decoder_ctl!($st, $request,) + }; + ($st:expr, $request:expr, $($arg:expr),*,) => { + opus_multistream_decoder_ctl!($st, $request, $($arg),*) + }; +} +pub unsafe fn opus_multistream_decoder_destroy(st: *mut OpusMSDecoder) { + free(st as *mut core::ffi::c_void); +} diff --git a/vendor/unsafe-libopus/src/src/opus_multistream_encoder.rs b/vendor/unsafe-libopus/src/src/opus_multistream_encoder.rs new file mode 100644 index 00000000..5b8de816 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_multistream_encoder.rs @@ -0,0 +1,1750 @@ +use crate::externs::{free, malloc}; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusMSEncoder { + pub(crate) layout: ChannelLayout, + pub(crate) arch: i32, + pub(crate) lfe_stream: i32, + pub(crate) application: i32, + pub(crate) variable_duration: i32, + pub(crate) mapping_type: MappingType, + pub(crate) bitrate_bps: i32, +} +pub type MappingType = u32; +pub const MAPPING_TYPE_AMBISONICS: MappingType = 2; +pub const MAPPING_TYPE_SURROUND: MappingType = 1; +pub const MAPPING_TYPE_NONE: MappingType = 0; +pub type opus_copy_channel_in_func = Option< + unsafe fn( + *mut opus_val16, + i32, + *const core::ffi::c_void, + i32, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), +>; +pub mod arch_h { + pub type opus_val32 = f32; + pub type opus_val16 = f32; +} +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} + +pub mod cpu_support_h { + #[inline] + pub unsafe fn opus_select_arch() -> i32 { + return 0; + } +} +pub use self::arch_h::{opus_val16, opus_val32}; +pub use self::cpu_support_h::opus_select_arch; +pub use self::stddef_h::{size_t, NULL}; +use crate::celt::bands::compute_band_energies; +use crate::celt::celt::resampling_factor; +use crate::celt::celt::{ + CELT_GET_MODE_REQUEST, OPUS_SET_ENERGY_MASK_REQUEST, OPUS_SET_LFE_REQUEST, +}; +use crate::celt::celt_encoder::celt_preemphasis; +use crate::celt::mathops::{celt_log2, isqrt32}; +use crate::celt::mdct::clt_mdct_forward_c; +use crate::celt::modes::OpusCustomMode; +use crate::celt::pitch::celt_inner_prod_c; +use crate::celt::quant_bands::amp2Log2; +use crate::externs::{memcpy, memset}; +use crate::src::analysis::downmix_func; +use crate::src::opus_defines::{ + OPUS_ALLOC_FAIL, OPUS_AUTO, OPUS_BAD_ARG, OPUS_BITRATE_MAX, OPUS_BUFFER_TOO_SMALL, + OPUS_FRAMESIZE_ARG, OPUS_GET_APPLICATION_REQUEST, OPUS_GET_BANDWIDTH_REQUEST, + OPUS_GET_BITRATE_REQUEST, OPUS_GET_COMPLEXITY_REQUEST, OPUS_GET_DTX_REQUEST, + OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST, + OPUS_GET_FORCE_CHANNELS_REQUEST, OPUS_GET_INBAND_FEC_REQUEST, OPUS_GET_LOOKAHEAD_REQUEST, + OPUS_GET_LSB_DEPTH_REQUEST, OPUS_GET_PACKET_LOSS_PERC_REQUEST, + OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PREDICTION_DISABLED_REQUEST, + OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_GET_SIGNAL_REQUEST, OPUS_GET_VBR_CONSTRAINT_REQUEST, + OPUS_GET_VBR_REQUEST, OPUS_INTERNAL_ERROR, OPUS_OK, OPUS_RESET_STATE, + OPUS_SET_APPLICATION_REQUEST, OPUS_SET_BANDWIDTH_REQUEST, OPUS_SET_BITRATE_REQUEST, + OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST, OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, + OPUS_SET_FORCE_CHANNELS_REQUEST, OPUS_SET_INBAND_FEC_REQUEST, OPUS_SET_LSB_DEPTH_REQUEST, + OPUS_SET_MAX_BANDWIDTH_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST, + OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_SET_PREDICTION_DISABLED_REQUEST, + OPUS_SET_SIGNAL_REQUEST, OPUS_SET_VBR_CONSTRAINT_REQUEST, OPUS_SET_VBR_REQUEST, + OPUS_UNIMPLEMENTED, +}; +use crate::src::opus_encoder::{downmix_float, downmix_int, frame_size_select, opus_encode_native}; +use crate::src::opus_multistream::{ + get_left_channel, get_mono_channel, get_right_channel, validate_layout, ChannelLayout, +}; +use crate::src::opus_private::{align, OPUS_GET_VOICE_RATIO_REQUEST, OPUS_SET_FORCE_MODE_REQUEST}; +use crate::varargs::VarArgs; +use crate::{ + opus_encoder_ctl, opus_encoder_get_size, opus_encoder_init, opus_repacketizer_cat, + opus_repacketizer_get_nb_frames, opus_repacketizer_init, opus_repacketizer_out_range_impl, + OpusEncoder, OpusRepacketizer, +}; + +pub const OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: i32 = 5120; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct VorbisLayout { + pub nb_streams: i32, + pub nb_coupled_streams: i32, + pub mapping: [u8; 8], +} +static mut vorbis_mappings: [VorbisLayout; 8] = [ + { + let init = VorbisLayout { + nb_streams: 1, + nb_coupled_streams: 0, + mapping: [0, 0, 0, 0, 0, 0, 0, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 1, + nb_coupled_streams: 1, + mapping: [0, 1, 0, 0, 0, 0, 0, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 2, + nb_coupled_streams: 1, + mapping: [0, 2, 1, 0, 0, 0, 0, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 2, + nb_coupled_streams: 2, + mapping: [0, 1, 2, 3, 0, 0, 0, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 3, + nb_coupled_streams: 2, + mapping: [0, 4, 1, 2, 3, 0, 0, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 4, + nb_coupled_streams: 2, + mapping: [0, 4, 1, 2, 3, 5, 0, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 4, + nb_coupled_streams: 3, + mapping: [0, 4, 1, 2, 3, 5, 6, 0], + }; + init + }, + { + let init = VorbisLayout { + nb_streams: 5, + nb_coupled_streams: 3, + mapping: [0, 6, 1, 2, 3, 4, 5, 7], + }; + init + }, +]; +unsafe fn ms_get_preemph_mem(st: *mut OpusMSEncoder) -> *mut opus_val32 { + let mut s: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + s = 0; + while s < (*st).layout.nb_streams { + if s < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + s += 1; + } + return ptr.offset( + (((*st).layout.nb_channels * 120) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) as isize, + ) as *mut core::ffi::c_void as *mut opus_val32; +} +unsafe fn ms_get_window_mem(st: *mut OpusMSEncoder) -> *mut opus_val32 { + let mut s: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + s = 0; + while s < (*st).layout.nb_streams { + if s < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + s += 1; + } + return ptr as *mut core::ffi::c_void as *mut opus_val32; +} +unsafe fn validate_ambisonics( + nb_channels: i32, + nb_streams: *mut i32, + nb_coupled_streams: *mut i32, +) -> i32 { + let mut order_plus_one: i32 = 0; + let mut acn_channels: i32 = 0; + let mut nondiegetic_channels: i32 = 0; + if nb_channels < 1 || nb_channels > 227 { + return 0; + } + order_plus_one = isqrt32(nb_channels as u32) as i32; + acn_channels = order_plus_one * order_plus_one; + nondiegetic_channels = nb_channels - acn_channels; + if nondiegetic_channels != 0 && nondiegetic_channels != 2 { + return 0; + } + if !nb_streams.is_null() { + *nb_streams = acn_channels + (nondiegetic_channels != 0) as i32; + } + if !nb_coupled_streams.is_null() { + *nb_coupled_streams = (nondiegetic_channels != 0) as i32; + } + return 1; +} +unsafe fn validate_encoder_layout(layout: *const ChannelLayout) -> i32 { + let mut s: i32 = 0; + s = 0; + while s < (*layout).nb_streams { + if s < (*layout).nb_coupled_streams { + if get_left_channel(layout, s, -1) == -1 { + return 0; + } + if get_right_channel(layout, s, -1) == -1 { + return 0; + } + } else if get_mono_channel(layout, s, -1) == -1 { + return 0; + } + s += 1; + } + return 1; +} +unsafe fn channel_pos(channels: i32, pos: *mut i32) { + if channels == 4 { + *pos.offset(0 as isize) = 1; + *pos.offset(1 as isize) = 3; + *pos.offset(2 as isize) = 1; + *pos.offset(3 as isize) = 3; + } else if channels == 3 || channels == 5 || channels == 6 { + *pos.offset(0 as isize) = 1; + *pos.offset(1 as isize) = 2; + *pos.offset(2 as isize) = 3; + *pos.offset(3 as isize) = 1; + *pos.offset(4 as isize) = 3; + *pos.offset(5 as isize) = 0; + } else if channels == 7 { + *pos.offset(0 as isize) = 1; + *pos.offset(1 as isize) = 2; + *pos.offset(2 as isize) = 3; + *pos.offset(3 as isize) = 1; + *pos.offset(4 as isize) = 3; + *pos.offset(5 as isize) = 2; + *pos.offset(6 as isize) = 0; + } else if channels == 8 { + *pos.offset(0 as isize) = 1; + *pos.offset(1 as isize) = 2; + *pos.offset(2 as isize) = 3; + *pos.offset(3 as isize) = 1; + *pos.offset(4 as isize) = 3; + *pos.offset(5 as isize) = 1; + *pos.offset(6 as isize) = 3; + *pos.offset(7 as isize) = 0; + } +} +unsafe fn logSum(a: opus_val16, b: opus_val16) -> opus_val16 { + let mut max: opus_val16 = 0.; + let mut diff: opus_val32 = 0.; + let mut frac: opus_val16 = 0.; + static mut diff_table: [opus_val16; 17] = [ + 0.5000000f32, + 0.2924813f32, + 0.1609640f32, + 0.0849625f32, + 0.0437314f32, + 0.0221971f32, + 0.0111839f32, + 0.0056136f32, + 0.0028123f32, + 0., + 0., + 0., + 0., + 0., + 0., + 0., + 0., + ]; + let mut low: i32 = 0; + if a > b { + max = a; + diff = a - b; + } else { + max = b; + diff = b - a; + } + if !(diff < 8.0f32) { + return max; + } + low = (2 as f32 * diff).floor() as i32; + frac = 2 as f32 * diff - low as f32; + return max + + diff_table[low as usize] + + frac * (diff_table[(low + 1) as usize] - diff_table[low as usize]); +} +pub unsafe fn surround_analysis( + celt_mode: *const OpusCustomMode, + pcm: *const core::ffi::c_void, + bandLogE: *mut opus_val16, + mem: *mut opus_val32, + preemph_mem: *mut opus_val32, + len: i32, + overlap: i32, + channels: i32, + rate: i32, + copy_channel_in: opus_copy_channel_in_func, + arch: i32, +) { + let mut c: i32 = 0; + let mut i: i32 = 0; + let mut LM: i32 = 0; + let mut pos: [i32; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; + let mut upsample: i32 = 0; + let mut frame_size: i32 = 0; + let mut freq_size: i32 = 0; + let mut channel_offset: opus_val16 = 0.; + let mut bandE: [opus_val32; 21] = [0.; 21]; + let mut maskLogE: [[opus_val16; 21]; 3] = [[0.; 21]; 3]; + upsample = resampling_factor(rate); + frame_size = len * upsample; + freq_size = if (960) < frame_size { 960 } else { frame_size }; + LM = 0; + while LM < (*celt_mode).maxLM { + if (*celt_mode).shortMdctSize << LM == frame_size { + break; + } + LM += 1; + } + let vla = (frame_size + overlap) as usize; + let mut in_0: Vec = ::std::vec::from_elem(0., vla); + let vla_0 = len as usize; + let mut x: Vec = ::std::vec::from_elem(0., vla_0); + let vla_1 = freq_size as usize; + let mut freq: Vec = ::std::vec::from_elem(0., vla_1); + channel_pos(channels, pos.as_mut_ptr()); + c = 0; + while c < 3 { + i = 0; + while i < 21 { + maskLogE[c as usize][i as usize] = -28.0f32; + i += 1; + } + c += 1; + } + c = 0; + while c < channels { + let mut frame: i32 = 0; + let nb_frames: i32 = frame_size / freq_size; + assert!(nb_frames * freq_size == frame_size); + memcpy( + in_0.as_mut_ptr() as *mut core::ffi::c_void, + mem.offset((c * overlap) as isize) as *const core::ffi::c_void, + (overlap as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * in_0 + .as_mut_ptr() + .offset_from(mem.offset((c * overlap) as isize)) + as i64) as u64, + ), + ); + (Some(copy_channel_in.expect("non-null function pointer"))) + .expect("non-null function pointer")( + x.as_mut_ptr(), + 1, + pcm, + channels, + c, + len, + NULL as *mut core::ffi::c_void, + ); + celt_preemphasis( + x.as_mut_ptr(), + in_0.as_mut_ptr().offset(overlap as isize), + frame_size, + 1, + upsample, + ((*celt_mode).preemph).as_ptr(), + preemph_mem.offset(c as isize), + 0, + ); + let mut sum: opus_val32 = 0.; + sum = celt_inner_prod_c(in_0.as_mut_ptr(), in_0.as_mut_ptr(), frame_size + overlap); + if !(sum < 1e18f32) || sum != sum { + memset( + in_0.as_mut_ptr() as *mut core::ffi::c_void, + 0, + ((frame_size + overlap) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + *preemph_mem.offset(c as isize) = 0 as opus_val32; + } + memset( + bandE.as_mut_ptr() as *mut core::ffi::c_void, + 0, + 21_u64.wrapping_mul(::core::mem::size_of::() as u64), + ); + frame = 0; + while frame < nb_frames { + let mut tmpE: [opus_val32; 21] = [0.; 21]; + clt_mdct_forward_c( + &(*celt_mode).mdct, + in_0.as_mut_ptr().offset((960 * frame) as isize), + freq.as_mut_ptr(), + (*celt_mode).window, + overlap, + (*celt_mode).maxLM - LM, + 1, + arch, + ); + if upsample != 1 { + let bound: i32 = freq_size / upsample; + i = 0; + while i < bound { + let ref mut fresh0 = *freq.as_mut_ptr().offset(i as isize); + *fresh0 *= upsample as f32; + i += 1; + } + while i < freq_size { + *freq.as_mut_ptr().offset(i as isize) = 0 as opus_val32; + i += 1; + } + } + compute_band_energies( + celt_mode, + freq.as_mut_ptr(), + tmpE.as_mut_ptr(), + 21, + 1, + LM, + arch, + ); + i = 0; + while i < 21 { + bandE[i as usize] = if bandE[i as usize] > tmpE[i as usize] { + bandE[i as usize] + } else { + tmpE[i as usize] + }; + i += 1; + } + frame += 1; + } + amp2Log2( + celt_mode, + 21, + 21, + bandE.as_mut_ptr(), + bandLogE.offset((21 * c) as isize), + 1, + ); + i = 1; + while i < 21 { + *bandLogE.offset((21 * c + i) as isize) = if *bandLogE.offset((21 * c + i) as isize) + > *bandLogE.offset((21 * c + i - 1) as isize) - 1.0f32 + { + *bandLogE.offset((21 * c + i) as isize) + } else { + *bandLogE.offset((21 * c + i - 1) as isize) - 1.0f32 + }; + i += 1; + } + i = 19; + while i >= 0 { + *bandLogE.offset((21 * c + i) as isize) = if *bandLogE.offset((21 * c + i) as isize) + > *bandLogE.offset((21 * c + i + 1) as isize) - 2.0f32 + { + *bandLogE.offset((21 * c + i) as isize) + } else { + *bandLogE.offset((21 * c + i + 1) as isize) - 2.0f32 + }; + i -= 1; + } + if pos[c as usize] == 1 { + i = 0; + while i < 21 { + maskLogE[0 as usize][i as usize] = logSum( + maskLogE[0 as usize][i as usize], + *bandLogE.offset((21 * c + i) as isize), + ); + i += 1; + } + } else if pos[c as usize] == 3 { + i = 0; + while i < 21 { + maskLogE[2 as usize][i as usize] = logSum( + maskLogE[2 as usize][i as usize], + *bandLogE.offset((21 * c + i) as isize), + ); + i += 1; + } + } else if pos[c as usize] == 2 { + i = 0; + while i < 21 { + maskLogE[0 as usize][i as usize] = logSum( + maskLogE[0 as usize][i as usize], + *bandLogE.offset((21 * c + i) as isize) - 0.5f32, + ); + maskLogE[2 as usize][i as usize] = logSum( + maskLogE[2 as usize][i as usize], + *bandLogE.offset((21 * c + i) as isize) - 0.5f32, + ); + i += 1; + } + } + memcpy( + mem.offset((c * overlap) as isize) as *mut core::ffi::c_void, + in_0.as_mut_ptr().offset(frame_size as isize) as *const core::ffi::c_void, + (overlap as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * mem + .offset((c * overlap) as isize) + .offset_from(in_0.as_mut_ptr().offset(frame_size as isize)) + as i64) as u64, + ), + ); + c += 1; + } + i = 0; + while i < 21 { + maskLogE[1 as usize][i as usize] = + if maskLogE[0 as usize][i as usize] < maskLogE[2 as usize][i as usize] { + maskLogE[0 as usize][i as usize] + } else { + maskLogE[2 as usize][i as usize] + }; + i += 1; + } + channel_offset = 0.5f32 * celt_log2(2.0f32 / (channels - 1) as f32); + c = 0; + while c < 3 { + i = 0; + while i < 21 { + maskLogE[c as usize][i as usize] += channel_offset; + i += 1; + } + c += 1; + } + c = 0; + while c < channels { + let mut mask: *mut opus_val16 = 0 as *mut opus_val16; + if pos[c as usize] != 0 { + mask = &mut *(*maskLogE + .as_mut_ptr() + .offset((*pos.as_mut_ptr().offset(c as isize) - 1) as isize)) + .as_mut_ptr() + .offset(0 as isize) as *mut opus_val16; + i = 0; + while i < 21 { + *bandLogE.offset((21 * c + i) as isize) = + *bandLogE.offset((21 * c + i) as isize) - *mask.offset(i as isize); + i += 1; + } + } else { + i = 0; + while i < 21 { + *bandLogE.offset((21 * c + i) as isize) = 0 as opus_val16; + i += 1; + } + } + c += 1; + } +} +pub unsafe fn opus_multistream_encoder_get_size(nb_streams: i32, nb_coupled_streams: i32) -> i32 { + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + if nb_streams < 1 || nb_coupled_streams > nb_streams || nb_coupled_streams < 0 { + return 0; + } + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + return align(::core::mem::size_of::() as u64 as i32) + + nb_coupled_streams * align(coupled_size) + + (nb_streams - nb_coupled_streams) * align(mono_size); +} +pub unsafe fn opus_multistream_surround_encoder_get_size( + channels: i32, + mapping_family: i32, +) -> i32 { + let mut nb_streams: i32 = 0; + let mut nb_coupled_streams: i32 = 0; + let mut size: i32 = 0; + if mapping_family == 0 { + if channels == 1 { + nb_streams = 1; + nb_coupled_streams = 0; + } else if channels == 2 { + nb_streams = 1; + nb_coupled_streams = 1; + } else { + return 0; + } + } else if mapping_family == 1 && channels <= 8 && channels >= 1 { + nb_streams = vorbis_mappings[(channels - 1) as usize].nb_streams; + nb_coupled_streams = vorbis_mappings[(channels - 1) as usize].nb_coupled_streams; + } else if mapping_family == 255 { + nb_streams = channels; + nb_coupled_streams = 0; + } else if mapping_family == 2 { + if validate_ambisonics(channels, &mut nb_streams, &mut nb_coupled_streams) == 0 { + return 0; + } + } else { + return 0; + } + size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); + if channels > 2 { + size = (size as u64).wrapping_add( + (channels as u64).wrapping_mul( + 120_u64 + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add(::core::mem::size_of::() as u64), + ), + ) as i32 as i32; + } + return size; +} +unsafe fn opus_multistream_encoder_init_impl( + st: *mut OpusMSEncoder, + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + mapping: *const u8, + application: i32, + mapping_type: MappingType, +) -> i32 { + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + if channels > 255 + || channels < 1 + || coupled_streams > streams + || streams < 1 + || coupled_streams < 0 + || streams > 255 - coupled_streams + { + return OPUS_BAD_ARG; + } + (*st).arch = opus_select_arch(); + (*st).layout.nb_channels = channels; + (*st).layout.nb_streams = streams; + (*st).layout.nb_coupled_streams = coupled_streams; + if mapping_type as u32 != MAPPING_TYPE_SURROUND as i32 as u32 { + (*st).lfe_stream = -1; + } + (*st).bitrate_bps = OPUS_AUTO; + (*st).application = application; + (*st).variable_duration = OPUS_FRAMESIZE_ARG; + i = 0; + while i < (*st).layout.nb_channels { + (*st).layout.mapping[i as usize] = *mapping.offset(i as isize); + i += 1; + } + if validate_layout(&mut (*st).layout) == 0 { + return OPUS_BAD_ARG; + } + if mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 + && validate_encoder_layout(&mut (*st).layout) == 0 + { + return OPUS_BAD_ARG; + } + if mapping_type as u32 == MAPPING_TYPE_AMBISONICS as i32 as u32 + && validate_ambisonics((*st).layout.nb_channels, NULL as *mut i32, NULL as *mut i32) == 0 + { + return OPUS_BAD_ARG; + } + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + i = 0; + while i < (*st).layout.nb_coupled_streams { + ret = opus_encoder_init(ptr as *mut OpusEncoder, Fs, 2, application); + if ret != OPUS_OK { + return ret; + } + if i == (*st).lfe_stream { + opus_encoder_ctl!(ptr as *mut OpusEncoder, OPUS_SET_LFE_REQUEST, 1,); + } + ptr = ptr.offset(align(coupled_size) as isize); + i += 1; + } + while i < (*st).layout.nb_streams { + ret = opus_encoder_init(ptr as *mut OpusEncoder, Fs, 1, application); + if i == (*st).lfe_stream { + opus_encoder_ctl!(ptr as *mut OpusEncoder, OPUS_SET_LFE_REQUEST, 1,); + } + if ret != OPUS_OK { + return ret; + } + ptr = ptr.offset(align(mono_size) as isize); + i += 1; + } + if mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + memset( + ms_get_preemph_mem(st) as *mut core::ffi::c_void, + 0, + (channels as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + memset( + ms_get_window_mem(st) as *mut core::ffi::c_void, + 0, + ((channels * 120) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } + (*st).mapping_type = mapping_type; + return OPUS_OK; +} +pub unsafe fn opus_multistream_encoder_init( + st: *mut OpusMSEncoder, + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + mapping: *const u8, + application: i32, +) -> i32 { + return opus_multistream_encoder_init_impl( + st, + Fs, + channels, + streams, + coupled_streams, + mapping, + application, + MAPPING_TYPE_NONE, + ); +} +pub unsafe fn opus_multistream_surround_encoder_init( + st: *mut OpusMSEncoder, + Fs: i32, + channels: i32, + mapping_family: i32, + streams: *mut i32, + coupled_streams: *mut i32, + mapping: *mut u8, + application: i32, +) -> i32 { + let mut mapping_type: MappingType = MAPPING_TYPE_NONE; + if channels > 255 || channels < 1 { + return OPUS_BAD_ARG; + } + (*st).lfe_stream = -1; + if mapping_family == 0 { + if channels == 1 { + *streams = 1; + *coupled_streams = 0; + *mapping.offset(0 as isize) = 0; + } else if channels == 2 { + *streams = 1; + *coupled_streams = 1; + *mapping.offset(0 as isize) = 0; + *mapping.offset(1 as isize) = 1; + } else { + return OPUS_UNIMPLEMENTED; + } + } else if mapping_family == 1 && channels <= 8 && channels >= 1 { + let mut i: i32 = 0; + *streams = vorbis_mappings[(channels - 1) as usize].nb_streams; + *coupled_streams = vorbis_mappings[(channels - 1) as usize].nb_coupled_streams; + i = 0; + while i < channels { + *mapping.offset(i as isize) = + vorbis_mappings[(channels - 1) as usize].mapping[i as usize]; + i += 1; + } + if channels >= 6 { + (*st).lfe_stream = *streams - 1; + } + } else if mapping_family == 255 { + let mut i_0: i32 = 0; + *streams = channels; + *coupled_streams = 0; + i_0 = 0; + while i_0 < channels { + *mapping.offset(i_0 as isize) = i_0 as u8; + i_0 += 1; + } + } else if mapping_family == 2 { + let mut i_1: i32 = 0; + if validate_ambisonics(channels, streams, coupled_streams) == 0 { + return OPUS_BAD_ARG; + } + i_1 = 0; + while i_1 < *streams - *coupled_streams { + *mapping.offset(i_1 as isize) = (i_1 + *coupled_streams * 2) as u8; + i_1 += 1; + } + i_1 = 0; + while i_1 < *coupled_streams * 2 { + *mapping.offset((i_1 + (*streams - *coupled_streams)) as isize) = i_1 as u8; + i_1 += 1; + } + } else { + return OPUS_UNIMPLEMENTED; + } + if channels > 2 && mapping_family == 1 { + mapping_type = MAPPING_TYPE_SURROUND; + } else if mapping_family == 2 { + mapping_type = MAPPING_TYPE_AMBISONICS; + } else { + mapping_type = MAPPING_TYPE_NONE; + } + return opus_multistream_encoder_init_impl( + st, + Fs, + channels, + *streams, + *coupled_streams, + mapping, + application, + mapping_type, + ); +} +pub unsafe fn opus_multistream_encoder_create( + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + mapping: *const u8, + application: i32, + error: *mut i32, +) -> *mut OpusMSEncoder { + let mut ret: i32 = 0; + let mut st: *mut OpusMSEncoder = 0 as *mut OpusMSEncoder; + if channels > 255 + || channels < 1 + || coupled_streams > streams + || streams < 1 + || coupled_streams < 0 + || streams > 255 - coupled_streams + { + if !error.is_null() { + *error = OPUS_BAD_ARG; + } + return NULL as *mut OpusMSEncoder; + } + st = malloc(opus_multistream_encoder_get_size(streams, coupled_streams) as size_t) + as *mut OpusMSEncoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusMSEncoder; + } + ret = opus_multistream_encoder_init( + st, + Fs, + channels, + streams, + coupled_streams, + mapping, + application, + ); + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusMSEncoder; + } + if !error.is_null() { + *error = ret; + } + return st; +} +pub unsafe fn opus_multistream_surround_encoder_create( + Fs: i32, + channels: i32, + mapping_family: i32, + streams: *mut i32, + coupled_streams: *mut i32, + mapping: *mut u8, + application: i32, + error: *mut i32, +) -> *mut OpusMSEncoder { + let mut ret: i32 = 0; + let mut size: i32 = 0; + let mut st: *mut OpusMSEncoder = 0 as *mut OpusMSEncoder; + if channels > 255 || channels < 1 { + if !error.is_null() { + *error = OPUS_BAD_ARG; + } + return NULL as *mut OpusMSEncoder; + } + size = opus_multistream_surround_encoder_get_size(channels, mapping_family); + if size == 0 { + if !error.is_null() { + *error = OPUS_UNIMPLEMENTED; + } + return NULL as *mut OpusMSEncoder; + } + st = malloc(size as size_t) as *mut OpusMSEncoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusMSEncoder; + } + ret = opus_multistream_surround_encoder_init( + st, + Fs, + channels, + mapping_family, + streams, + coupled_streams, + mapping, + application, + ); + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusMSEncoder; + } + if !error.is_null() { + *error = ret; + } + return st; +} +unsafe fn surround_rate_allocation( + st: *mut OpusMSEncoder, + rate: *mut i32, + frame_size: i32, + Fs: i32, +) { + let mut i: i32 = 0; + let mut channel_rate: i32 = 0; + let mut stream_offset: i32 = 0; + let mut lfe_offset: i32 = 0; + let mut coupled_ratio: i32 = 0; + let mut lfe_ratio: i32 = 0; + let mut nb_lfe: i32 = 0; + let mut nb_uncoupled: i32 = 0; + let mut nb_coupled: i32 = 0; + let mut nb_normal: i32 = 0; + let mut channel_offset: i32 = 0; + let mut bitrate: i32 = 0; + let mut total: i32 = 0; + nb_lfe = ((*st).lfe_stream != -1) as i32; + nb_coupled = (*st).layout.nb_coupled_streams; + nb_uncoupled = (*st).layout.nb_streams - nb_coupled - nb_lfe; + nb_normal = 2 * nb_coupled + nb_uncoupled; + channel_offset = 40 + * (if 50 > Fs / frame_size { + 50 + } else { + Fs / frame_size + }); + if (*st).bitrate_bps == OPUS_AUTO { + bitrate = nb_normal * (channel_offset + Fs + 10000) + 8000 * nb_lfe; + } else if (*st).bitrate_bps == OPUS_BITRATE_MAX { + bitrate = nb_normal * 300000 + nb_lfe * 128000; + } else { + bitrate = (*st).bitrate_bps; + } + lfe_offset = (if (bitrate / 20) < 3000 { + bitrate / 20 + } else { + 3000 + }) + 15 + * (if 50 > Fs / frame_size { + 50 + } else { + Fs / frame_size + }); + stream_offset = (bitrate - channel_offset * nb_normal - lfe_offset * nb_lfe) / nb_normal / 2; + stream_offset = if 0 + > (if (20000) < stream_offset { + 20000 + } else { + stream_offset + }) { + 0 + } else if (20000) < stream_offset { + 20000 + } else { + stream_offset + }; + coupled_ratio = 512; + lfe_ratio = 32; + total = (nb_uncoupled << 8) + coupled_ratio * nb_coupled + nb_lfe * lfe_ratio; + channel_rate = (256 + * (bitrate + - lfe_offset * nb_lfe + - stream_offset * (nb_coupled + nb_uncoupled) + - channel_offset * nb_normal) as i64 + / total as i64) as i32; + i = 0; + while i < (*st).layout.nb_streams { + if i < (*st).layout.nb_coupled_streams { + *rate.offset(i as isize) = 2 * channel_offset + + (if 0 > stream_offset + (channel_rate * coupled_ratio >> 8) { + 0 + } else { + stream_offset + (channel_rate * coupled_ratio >> 8) + }); + } else if i != (*st).lfe_stream { + *rate.offset(i as isize) = channel_offset + + (if 0 > stream_offset + channel_rate { + 0 + } else { + stream_offset + channel_rate + }); + } else { + *rate.offset(i as isize) = if 0 > lfe_offset + (channel_rate * lfe_ratio >> 8) { + 0 + } else { + lfe_offset + (channel_rate * lfe_ratio >> 8) + }; + } + i += 1; + } +} +unsafe fn ambisonics_rate_allocation( + st: *mut OpusMSEncoder, + rate: *mut i32, + frame_size: i32, + Fs: i32, +) { + let mut i: i32 = 0; + let mut total_rate: i32 = 0; + let mut per_stream_rate: i32 = 0; + let nb_channels: i32 = (*st).layout.nb_streams + (*st).layout.nb_coupled_streams; + if (*st).bitrate_bps == OPUS_AUTO { + total_rate = ((*st).layout.nb_coupled_streams + (*st).layout.nb_streams) + * (Fs + 60 * Fs / frame_size) + + (*st).layout.nb_streams * 15000; + } else if (*st).bitrate_bps == OPUS_BITRATE_MAX { + total_rate = nb_channels * 320000; + } else { + total_rate = (*st).bitrate_bps; + } + per_stream_rate = total_rate / (*st).layout.nb_streams; + i = 0; + while i < (*st).layout.nb_streams { + *rate.offset(i as isize) = per_stream_rate; + i += 1; + } +} +unsafe fn rate_allocation(st: *mut OpusMSEncoder, rate: *mut i32, frame_size: i32) -> i32 { + let mut i: i32 = 0; + let mut rate_sum: i32 = 0; + let mut Fs: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + opus_encoder_ctl!( + ptr as *mut OpusEncoder, + OPUS_GET_SAMPLE_RATE_REQUEST, + &mut Fs + ); + if (*st).mapping_type as u32 == MAPPING_TYPE_AMBISONICS as i32 as u32 { + ambisonics_rate_allocation(st, rate, frame_size, Fs); + } else { + surround_rate_allocation(st, rate, frame_size, Fs); + } + i = 0; + while i < (*st).layout.nb_streams { + *rate.offset(i as isize) = if *rate.offset(i as isize) > 500 { + *rate.offset(i as isize) + } else { + 500 + }; + rate_sum += *rate.offset(i as isize); + i += 1; + } + return rate_sum; +} +pub unsafe fn opus_multistream_encode_native( + st: *mut OpusMSEncoder, + copy_channel_in: opus_copy_channel_in_func, + pcm: *const core::ffi::c_void, + analysis_frame_size: i32, + mut data: *mut u8, + mut max_data_bytes: i32, + lsb_depth: i32, + downmix: downmix_func, + float_api: i32, + user_data: *mut core::ffi::c_void, +) -> i32 { + let mut Fs: i32 = 0; + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + let mut s: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + let mut tot_size: i32 = 0; + let mut tmp_data: [u8; 7662] = [0; 7662]; + let mut rp: OpusRepacketizer = OpusRepacketizer { + toc: 0, + nb_frames: 0, + frames: [0 as *const u8; 48], + len: [0; 48], + framesize: 0, + }; + let mut vbr: i32 = 0; + let mut celt_mode: *const OpusCustomMode = 0 as *const OpusCustomMode; + let mut bitrates: [i32; 256] = [0; 256]; + let mut bandLogE: [opus_val16; 42] = [0.; 42]; + let mut mem: *mut opus_val32 = NULL as *mut opus_val32; + let mut preemph_mem: *mut opus_val32 = NULL as *mut opus_val32; + let mut frame_size: i32 = 0; + let mut rate_sum: i32 = 0; + let mut smallest_packet: i32 = 0; + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + preemph_mem = ms_get_preemph_mem(st); + mem = ms_get_window_mem(st); + } + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + opus_encoder_ctl!( + ptr as *mut OpusEncoder, + OPUS_GET_SAMPLE_RATE_REQUEST, + &mut Fs + ); + opus_encoder_ctl!(ptr as *mut OpusEncoder, OPUS_GET_VBR_REQUEST, &mut vbr); + opus_encoder_ctl!( + ptr as *mut OpusEncoder, + CELT_GET_MODE_REQUEST, + &mut celt_mode + ); + frame_size = frame_size_select(analysis_frame_size, (*st).variable_duration, Fs); + if frame_size <= 0 { + return OPUS_BAD_ARG; + } + smallest_packet = (*st).layout.nb_streams * 2 - 1; + if Fs / frame_size == 10 { + smallest_packet += (*st).layout.nb_streams; + } + if max_data_bytes < smallest_packet { + return OPUS_BUFFER_TOO_SMALL; + } + let vla = (2 * frame_size) as usize; + let mut buf: Vec = ::std::vec::from_elem(0., vla); + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + let vla_0 = (21 * (*st).layout.nb_channels) as usize; + let mut bandSMR: Vec = ::std::vec::from_elem(0., vla_0); + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + surround_analysis( + celt_mode, + pcm, + bandSMR.as_mut_ptr(), + mem, + preemph_mem, + frame_size, + 120, + (*st).layout.nb_channels, + Fs, + copy_channel_in, + (*st).arch, + ); + } + rate_sum = rate_allocation(st, bitrates.as_mut_ptr(), frame_size); + if vbr == 0 { + if (*st).bitrate_bps == OPUS_AUTO { + max_data_bytes = if max_data_bytes < 3 * rate_sum / (3 * 8 * Fs / frame_size) { + max_data_bytes + } else { + 3 * rate_sum / (3 * 8 * Fs / frame_size) + }; + } else if (*st).bitrate_bps != OPUS_BITRATE_MAX { + max_data_bytes = if max_data_bytes + < (if smallest_packet > 3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size) { + smallest_packet + } else { + 3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size) + }) { + max_data_bytes + } else if smallest_packet > 3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size) { + smallest_packet + } else { + 3 * (*st).bitrate_bps / (3 * 8 * Fs / frame_size) + }; + } + } + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + s = 0; + while s < (*st).layout.nb_streams { + let mut enc: *mut OpusEncoder = 0 as *mut OpusEncoder; + enc = ptr as *mut OpusEncoder; + if s < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + opus_encoder_ctl!(enc, OPUS_SET_BITRATE_REQUEST, bitrates[s as usize]); + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + let mut equiv_rate: i32 = 0; + equiv_rate = (*st).bitrate_bps; + if (frame_size * 50) < Fs { + equiv_rate -= 60 * (Fs / frame_size - 50) * (*st).layout.nb_channels; + } + if equiv_rate > 10000 * (*st).layout.nb_channels { + opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1105); + } else if equiv_rate > 7000 * (*st).layout.nb_channels { + opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1104); + } else if equiv_rate > 5000 * (*st).layout.nb_channels { + opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1103); + } else { + opus_encoder_ctl!(enc, OPUS_SET_BANDWIDTH_REQUEST, 1101); + } + if s < (*st).layout.nb_coupled_streams { + opus_encoder_ctl!(enc, OPUS_SET_FORCE_MODE_REQUEST, 1002); + opus_encoder_ctl!(enc, OPUS_SET_FORCE_CHANNELS_REQUEST, 2); + } + } else if (*st).mapping_type as u32 == MAPPING_TYPE_AMBISONICS as i32 as u32 { + opus_encoder_ctl!(enc, OPUS_SET_FORCE_MODE_REQUEST, 1002); + } + s += 1; + } + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + tot_size = 0; + s = 0; + while s < (*st).layout.nb_streams { + let mut enc_0: *mut OpusEncoder = 0 as *mut OpusEncoder; + let mut len: i32 = 0; + let mut curr_max: i32 = 0; + let mut c1: i32 = 0; + let mut c2: i32 = 0; + let mut ret: i32 = 0; + opus_repacketizer_init(&mut rp); + enc_0 = ptr as *mut OpusEncoder; + if s < (*st).layout.nb_coupled_streams { + let mut i: i32 = 0; + let mut left: i32 = 0; + let mut right: i32 = 0; + left = get_left_channel(&mut (*st).layout, s, -1); + right = get_right_channel(&mut (*st).layout, s, -1); + (Some(copy_channel_in.expect("non-null function pointer"))) + .expect("non-null function pointer")( + buf.as_mut_ptr(), + 2, + pcm, + (*st).layout.nb_channels, + left, + frame_size, + user_data, + ); + (Some(copy_channel_in.expect("non-null function pointer"))) + .expect("non-null function pointer")( + buf.as_mut_ptr().offset(1 as isize), + 2, + pcm, + (*st).layout.nb_channels, + right, + frame_size, + user_data, + ); + ptr = ptr.offset(align(coupled_size) as isize); + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + i = 0; + while i < 21 { + bandLogE[i as usize] = *bandSMR.as_mut_ptr().offset((21 * left + i) as isize); + bandLogE[(21 + i) as usize] = + *bandSMR.as_mut_ptr().offset((21 * right + i) as isize); + i += 1; + } + } + c1 = left; + c2 = right; + } else { + let mut i_0: i32 = 0; + let chan: i32 = get_mono_channel(&mut (*st).layout, s, -1); + (Some(copy_channel_in.expect("non-null function pointer"))) + .expect("non-null function pointer")( + buf.as_mut_ptr(), + 1, + pcm, + (*st).layout.nb_channels, + chan, + frame_size, + user_data, + ); + ptr = ptr.offset(align(mono_size) as isize); + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + i_0 = 0; + while i_0 < 21 { + bandLogE[i_0 as usize] = + *bandSMR.as_mut_ptr().offset((21 * chan + i_0) as isize); + i_0 += 1; + } + } + c1 = chan; + c2 = -1; + } + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + opus_encoder_ctl!( + enc_0, + OPUS_SET_ENERGY_MASK_REQUEST, + bandLogE.as_mut_ptr().offset( + bandLogE.as_mut_ptr().offset_from(bandLogE.as_mut_ptr()) as i64 as isize, + ), + ); + } + curr_max = max_data_bytes - tot_size; + curr_max -= if 0 > 2 * ((*st).layout.nb_streams - s - 1) - 1 { + 0 + } else { + 2 * ((*st).layout.nb_streams - s - 1) - 1 + }; + if Fs / frame_size == 10 { + curr_max -= (*st).layout.nb_streams - s - 1; + } + curr_max = if curr_max < 6 * 1275 + 12 { + curr_max + } else { + 6 * 1275 + 12 + }; + if s != (*st).layout.nb_streams - 1 { + curr_max -= if curr_max > 253 { 2 } else { 1 }; + } + if vbr == 0 && s == (*st).layout.nb_streams - 1 { + opus_encoder_ctl!( + enc_0, + OPUS_SET_BITRATE_REQUEST, + curr_max * (8 * Fs / frame_size), + ); + } + len = opus_encode_native( + enc_0, + buf.as_mut_ptr(), + frame_size, + tmp_data.as_mut_ptr(), + curr_max, + lsb_depth, + pcm, + analysis_frame_size, + c1, + c2, + (*st).layout.nb_channels, + downmix, + float_api, + ); + if len < 0 { + return len; + } + ret = opus_repacketizer_cat(&mut rp, tmp_data.as_mut_ptr(), len); + if ret != OPUS_OK { + return OPUS_INTERNAL_ERROR; + } + len = opus_repacketizer_out_range_impl( + &mut rp, + 0, + opus_repacketizer_get_nb_frames(&mut rp), + data, + max_data_bytes - tot_size, + (s != (*st).layout.nb_streams - 1) as i32, + (vbr == 0 && s == (*st).layout.nb_streams - 1) as i32, + ); + data = data.offset(len as isize); + tot_size += len; + s += 1; + } + return tot_size; +} +unsafe fn opus_copy_channel_in_float( + dst: *mut opus_val16, + dst_stride: i32, + src: *const core::ffi::c_void, + src_stride: i32, + src_channel: i32, + frame_size: i32, + _user_data: *mut core::ffi::c_void, +) { + let mut float_src: *const f32 = 0 as *const f32; + let mut i: i32 = 0; + float_src = src as *const f32; + i = 0; + while i < frame_size { + *dst.offset((i * dst_stride) as isize) = + *float_src.offset((i * src_stride + src_channel) as isize); + i += 1; + } +} +unsafe fn opus_copy_channel_in_short( + dst: *mut opus_val16, + dst_stride: i32, + src: *const core::ffi::c_void, + src_stride: i32, + src_channel: i32, + frame_size: i32, + _user_data: *mut core::ffi::c_void, +) { + let mut short_src: *const i16 = 0 as *const i16; + let mut i: i32 = 0; + short_src = src as *const i16; + i = 0; + while i < frame_size { + *dst.offset((i * dst_stride) as isize) = 1 as f32 / 32768.0f32 + * *short_src.offset((i * src_stride + src_channel) as isize) as i32 as f32; + i += 1; + } +} +pub unsafe fn opus_multistream_encode_float( + st: *mut OpusMSEncoder, + pcm: *const opus_val16, + frame_size: i32, + data: *mut u8, + max_data_bytes: i32, +) -> i32 { + return opus_multistream_encode_native( + st, + Some( + opus_copy_channel_in_float + as unsafe fn( + *mut opus_val16, + i32, + *const core::ffi::c_void, + i32, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + pcm as *const core::ffi::c_void, + frame_size, + data, + max_data_bytes, + 24, + Some( + downmix_float + as unsafe fn( + *const core::ffi::c_void, + *mut opus_val32, + i32, + i32, + i32, + i32, + i32, + ) -> (), + ), + 1, + NULL as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_multistream_encode( + st: *mut OpusMSEncoder, + pcm: *const i16, + frame_size: i32, + data: *mut u8, + max_data_bytes: i32, +) -> i32 { + return opus_multistream_encode_native( + st, + Some( + opus_copy_channel_in_short + as unsafe fn( + *mut opus_val16, + i32, + *const core::ffi::c_void, + i32, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + pcm as *const core::ffi::c_void, + frame_size, + data, + max_data_bytes, + 16, + Some( + downmix_int + as unsafe fn( + *const core::ffi::c_void, + *mut opus_val32, + i32, + i32, + i32, + i32, + i32, + ) -> (), + ), + 0, + NULL as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_multistream_encoder_ctl_va_list( + st: *mut OpusMSEncoder, + request: i32, + mut ap: VarArgs, +) -> i32 { + let mut current_block: u64; + let mut coupled_size: i32 = 0; + let mut mono_size: i32 = 0; + let mut ptr: *mut i8 = 0 as *mut i8; + let mut ret: i32 = OPUS_OK; + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + ptr = (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize); + match request { + OPUS_SET_BITRATE_REQUEST => { + let mut value: i32 = ap.arg::(); + if value != OPUS_AUTO && value != OPUS_BITRATE_MAX { + if value <= 0 { + current_block = 11382675479785311092; + } else { + value = if 300000 * (*st).layout.nb_channels + < (if 500 * (*st).layout.nb_channels > value { + 500 * (*st).layout.nb_channels + } else { + value + }) { + 300000 * (*st).layout.nb_channels + } else if 500 * (*st).layout.nb_channels > value { + 500 * (*st).layout.nb_channels + } else { + value + }; + current_block = 10879442775620481940; + } + } else { + current_block = 10879442775620481940; + } + match current_block { + 11382675479785311092 => {} + _ => { + (*st).bitrate_bps = value; + current_block = 2616667235040759262; + } + } + } + OPUS_GET_BITRATE_REQUEST => { + let mut s: i32 = 0; + let value_0 = ap.arg::<&mut i32>(); + *value_0 = 0; + s = 0; + while s < (*st).layout.nb_streams { + let mut rate: i32 = 0; + let mut enc: *mut OpusEncoder = 0 as *mut OpusEncoder; + enc = ptr as *mut OpusEncoder; + if s < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + opus_encoder_ctl!(enc, request, &mut rate); + *value_0 += rate; + s += 1; + } + current_block = 2616667235040759262; + } + OPUS_GET_LSB_DEPTH_REQUEST + | OPUS_GET_VBR_REQUEST + | OPUS_GET_APPLICATION_REQUEST + | OPUS_GET_BANDWIDTH_REQUEST + | OPUS_GET_COMPLEXITY_REQUEST + | OPUS_GET_PACKET_LOSS_PERC_REQUEST + | OPUS_GET_DTX_REQUEST + | OPUS_GET_VOICE_RATIO_REQUEST + | OPUS_GET_VBR_CONSTRAINT_REQUEST + | OPUS_GET_SIGNAL_REQUEST + | OPUS_GET_LOOKAHEAD_REQUEST + | OPUS_GET_SAMPLE_RATE_REQUEST + | OPUS_GET_INBAND_FEC_REQUEST + | OPUS_GET_FORCE_CHANNELS_REQUEST + | OPUS_GET_PREDICTION_DISABLED_REQUEST + | OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => { + let mut enc_0: *mut OpusEncoder = 0 as *mut OpusEncoder; + let value_1 = ap.arg::<&mut i32>(); + enc_0 = ptr as *mut OpusEncoder; + ret = opus_encoder_ctl!(enc_0, request, value_1); + current_block = 2616667235040759262; + } + OPUS_GET_FINAL_RANGE_REQUEST => { + let mut s_0: i32 = 0; + let value_2 = ap.arg::<&mut u32>(); + let mut tmp: u32 = 0; + *value_2 = 0; + s_0 = 0; + while s_0 < (*st).layout.nb_streams { + let mut enc_1: *mut OpusEncoder = 0 as *mut OpusEncoder; + enc_1 = ptr as *mut OpusEncoder; + if s_0 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + ret = opus_encoder_ctl!(enc_1, request, &mut tmp); + if ret != OPUS_OK { + break; + } + *value_2 ^= tmp; + s_0 += 1; + } + current_block = 2616667235040759262; + } + OPUS_SET_LSB_DEPTH_REQUEST + | OPUS_SET_COMPLEXITY_REQUEST + | OPUS_SET_VBR_REQUEST + | OPUS_SET_VBR_CONSTRAINT_REQUEST + | OPUS_SET_MAX_BANDWIDTH_REQUEST + | OPUS_SET_BANDWIDTH_REQUEST + | OPUS_SET_SIGNAL_REQUEST + | OPUS_SET_APPLICATION_REQUEST + | OPUS_SET_INBAND_FEC_REQUEST + | OPUS_SET_PACKET_LOSS_PERC_REQUEST + | OPUS_SET_DTX_REQUEST + | OPUS_SET_FORCE_MODE_REQUEST + | OPUS_SET_FORCE_CHANNELS_REQUEST + | OPUS_SET_PREDICTION_DISABLED_REQUEST + | OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => { + let mut s_1: i32 = 0; + let value_3: i32 = ap.arg::(); + s_1 = 0; + while s_1 < (*st).layout.nb_streams { + let mut enc_2: *mut OpusEncoder = 0 as *mut OpusEncoder; + enc_2 = ptr as *mut OpusEncoder; + if s_1 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + ret = opus_encoder_ctl!(enc_2, request, value_3); + if ret != OPUS_OK { + break; + } + s_1 += 1; + } + current_block = 2616667235040759262; + } + OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST => { + let mut s_2: i32 = 0; + let mut stream_id: i32 = 0; + let mut value_4: *mut *mut OpusEncoder = 0 as *mut *mut OpusEncoder; + stream_id = ap.arg::(); + if stream_id < 0 || stream_id >= (*st).layout.nb_streams { + current_block = 11382675479785311092; + } else { + value_4 = ap.arg::<&mut *mut OpusEncoder>(); + s_2 = 0; + while s_2 < stream_id { + if s_2 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + s_2 += 1; + } + *value_4 = ptr as *mut OpusEncoder; + current_block = 2616667235040759262; + } + } + OPUS_SET_EXPERT_FRAME_DURATION_REQUEST => { + let value_5: i32 = ap.arg::(); + (*st).variable_duration = value_5; + current_block = 2616667235040759262; + } + OPUS_GET_EXPERT_FRAME_DURATION_REQUEST => { + let value_6 = ap.arg::<&mut i32>(); + *value_6 = (*st).variable_duration; + current_block = 2616667235040759262; + } + OPUS_RESET_STATE => { + let mut s_3: i32 = 0; + if (*st).mapping_type as u32 == MAPPING_TYPE_SURROUND as i32 as u32 { + memset( + ms_get_preemph_mem(st) as *mut core::ffi::c_void, + 0, + ((*st).layout.nb_channels as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + memset( + ms_get_window_mem(st) as *mut core::ffi::c_void, + 0, + (((*st).layout.nb_channels * 120) as u64) + .wrapping_mul(::core::mem::size_of::() as u64), + ); + } + s_3 = 0; + while s_3 < (*st).layout.nb_streams { + let mut enc_3: *mut OpusEncoder = 0 as *mut OpusEncoder; + enc_3 = ptr as *mut OpusEncoder; + if s_3 < (*st).layout.nb_coupled_streams { + ptr = ptr.offset(align(coupled_size) as isize); + } else { + ptr = ptr.offset(align(mono_size) as isize); + } + ret = opus_encoder_ctl!(enc_3, OPUS_RESET_STATE); + if ret != OPUS_OK { + break; + } + s_3 += 1; + } + current_block = 2616667235040759262; + } + _ => { + ret = OPUS_UNIMPLEMENTED; + current_block = 2616667235040759262; + } + } + match current_block { + 2616667235040759262 => return ret, + _ => return OPUS_BAD_ARG, + }; +} +pub unsafe fn opus_multistream_encoder_ctl_impl( + st: *mut OpusMSEncoder, + request: i32, + args: VarArgs, +) -> i32 { + let mut ret: i32 = 0; + ret = opus_multistream_encoder_ctl_va_list(st, request, args); + return ret; +} +#[macro_export] +macro_rules! opus_multistream_encoder_ctl { + ($st:expr, $request:expr, $($arg:expr),*) => { + $crate::opus_multistream_encoder_ctl_impl($st, $request, $crate::varargs!($($arg),*)) + }; + ($st:expr, $request:expr) => { + opus_multistream_encoder_ctl!($st, $request,) + }; + ($st:expr, $request:expr, $($arg:expr),*,) => { + opus_multistream_encoder_ctl!($st, $request, $($arg),*) + }; +} +pub unsafe fn opus_multistream_encoder_destroy(st: *mut OpusMSEncoder) { + free(st as *mut core::ffi::c_void); +} diff --git a/vendor/unsafe-libopus/src/src/opus_private.rs b/vendor/unsafe-libopus/src/src/opus_private.rs new file mode 100644 index 00000000..1c4a8b75 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_private.rs @@ -0,0 +1,17 @@ +pub const MODE_SILK_ONLY: i32 = 1000; +pub const MODE_HYBRID: i32 = 1001; +pub const MODE_CELT_ONLY: i32 = 1002; + +pub const OPUS_SET_VOICE_RATIO_REQUEST: i32 = 11018; +pub const OPUS_GET_VOICE_RATIO_REQUEST: i32 = 11019; +pub const OPUS_SET_FORCE_MODE_REQUEST: i32 = 11002; + +#[inline] +pub fn align(i: i32) -> i32 { + let alignment: u32 = 8 as u64 as u32; + return (i as u32) + .wrapping_add(alignment) + .wrapping_sub(1) + .wrapping_div(alignment) + .wrapping_mul(alignment) as i32; +} diff --git a/vendor/unsafe-libopus/src/src/opus_projection_decoder.rs b/vendor/unsafe-libopus/src/src/opus_projection_decoder.rs new file mode 100644 index 00000000..1193753e --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_projection_decoder.rs @@ -0,0 +1,311 @@ +use crate::externs::{free, malloc}; + +pub mod arch_h { + pub type opus_val16 = f32; +} +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} +pub use self::arch_h::opus_val16; +pub use self::stddef_h::{size_t, NULL}; +use crate::src::opus_defines::{OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_OK}; + +use crate::externs::memset; +use crate::src::mapping_matrix::{ + mapping_matrix_get_size, mapping_matrix_init, mapping_matrix_multiply_channel_out_float, + mapping_matrix_multiply_channel_out_short, MappingMatrix, +}; +use crate::src::opus_multistream_decoder::{ + opus_multistream_decode_native, opus_multistream_decoder_ctl_va_list, +}; +use crate::src::opus_private::align; +use crate::varargs::VarArgs; +use crate::{opus_multistream_decoder_get_size, opus_multistream_decoder_init, OpusMSDecoder}; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusProjectionDecoder { + pub demixing_matrix_size_in_bytes: i32, +} +unsafe fn opus_projection_copy_channel_out_float( + dst: *mut core::ffi::c_void, + dst_stride: i32, + dst_channel: i32, + src: *const opus_val16, + src_stride: i32, + frame_size: i32, + user_data: *mut core::ffi::c_void, +) { + let mut float_dst: *mut f32 = 0 as *mut f32; + let mut matrix: *const MappingMatrix = 0 as *const MappingMatrix; + float_dst = dst as *mut f32; + matrix = user_data as *const MappingMatrix; + if dst_channel == 0 { + memset( + float_dst as *mut core::ffi::c_void, + 0, + ((frame_size * dst_stride) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } + if !src.is_null() { + mapping_matrix_multiply_channel_out_float( + matrix, + src, + dst_channel, + src_stride, + float_dst, + dst_stride, + frame_size, + ); + } +} +unsafe fn opus_projection_copy_channel_out_short( + dst: *mut core::ffi::c_void, + dst_stride: i32, + dst_channel: i32, + src: *const opus_val16, + src_stride: i32, + frame_size: i32, + user_data: *mut core::ffi::c_void, +) { + let mut short_dst: *mut i16 = 0 as *mut i16; + let mut matrix: *const MappingMatrix = 0 as *const MappingMatrix; + short_dst = dst as *mut i16; + matrix = user_data as *const MappingMatrix; + if dst_channel == 0 { + memset( + short_dst as *mut core::ffi::c_void, + 0, + ((frame_size * dst_stride) as u64).wrapping_mul(::core::mem::size_of::() as u64), + ); + } + if !src.is_null() { + mapping_matrix_multiply_channel_out_short( + matrix, + src, + dst_channel, + src_stride, + short_dst, + dst_stride, + frame_size, + ); + } +} +unsafe fn get_dec_demixing_matrix(st: *mut OpusProjectionDecoder) -> *mut MappingMatrix { + return (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize) + as *mut core::ffi::c_void as *mut MappingMatrix; +} +unsafe fn get_multistream_decoder(st: *mut OpusProjectionDecoder) -> *mut OpusMSDecoder { + return (st as *mut i8).offset(align( + (::core::mem::size_of::() as u64) + .wrapping_add((*st).demixing_matrix_size_in_bytes as u64) as i32, + ) as isize) as *mut core::ffi::c_void as *mut OpusMSDecoder; +} +pub unsafe fn opus_projection_decoder_get_size( + channels: i32, + streams: i32, + coupled_streams: i32, +) -> i32 { + let mut matrix_size: i32 = 0; + let mut decoder_size: i32 = 0; + matrix_size = mapping_matrix_get_size(streams + coupled_streams, channels); + if matrix_size == 0 { + return 0; + } + decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams); + if decoder_size == 0 { + return 0; + } + return align(::core::mem::size_of::() as u64 as i32) + + matrix_size + + decoder_size; +} +pub unsafe fn opus_projection_decoder_init( + st: *mut OpusProjectionDecoder, + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + demixing_matrix: *mut u8, + demixing_matrix_size: i32, +) -> i32 { + let mut nb_input_streams: i32 = 0; + let mut expected_matrix_size: i32 = 0; + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut mapping: [u8; 255] = [0; 255]; + nb_input_streams = streams + coupled_streams; + expected_matrix_size = ((nb_input_streams * channels) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) as i32; + if expected_matrix_size != demixing_matrix_size { + return OPUS_BAD_ARG; + } + let vla = (nb_input_streams * channels) as usize; + let mut buf: Vec = ::std::vec::from_elem(0, vla); + i = 0; + while i < nb_input_streams * channels { + let mut s: i32 = (*demixing_matrix.offset((2 * i + 1) as isize) as i32) << 8 + | *demixing_matrix.offset((2 * i) as isize) as i32; + s = (s & 0xffff ^ 0x8000) - 0x8000; + *buf.as_mut_ptr().offset(i as isize) = s as i16; + i += 1; + } + (*st).demixing_matrix_size_in_bytes = mapping_matrix_get_size(channels, nb_input_streams); + if (*st).demixing_matrix_size_in_bytes == 0 { + return OPUS_BAD_ARG; + } + mapping_matrix_init( + get_dec_demixing_matrix(st), + channels, + nb_input_streams, + 0, + buf.as_mut_ptr(), + demixing_matrix_size, + ); + i = 0; + while i < channels { + mapping[i as usize] = i as u8; + i += 1; + } + ret = opus_multistream_decoder_init( + get_multistream_decoder(st), + Fs, + channels, + streams, + coupled_streams, + mapping.as_mut_ptr(), + ); + return ret; +} +pub unsafe fn opus_projection_decoder_create( + Fs: i32, + channels: i32, + streams: i32, + coupled_streams: i32, + demixing_matrix: *mut u8, + demixing_matrix_size: i32, + error: *mut i32, +) -> *mut OpusProjectionDecoder { + let mut size: i32 = 0; + let mut ret: i32 = 0; + let mut st: *mut OpusProjectionDecoder = 0 as *mut OpusProjectionDecoder; + size = opus_projection_decoder_get_size(channels, streams, coupled_streams); + if size == 0 { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusProjectionDecoder; + } + st = malloc(size as size_t) as *mut OpusProjectionDecoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusProjectionDecoder; + } + ret = opus_projection_decoder_init( + st, + Fs, + channels, + streams, + coupled_streams, + demixing_matrix, + demixing_matrix_size, + ); + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusProjectionDecoder; + } + if !error.is_null() { + *error = ret; + } + return st; +} +pub unsafe fn opus_projection_decode( + st: *mut OpusProjectionDecoder, + data: *const u8, + len: i32, + pcm: *mut i16, + frame_size: i32, + decode_fec: i32, +) -> i32 { + return opus_multistream_decode_native( + get_multistream_decoder(st), + data, + len, + pcm as *mut core::ffi::c_void, + Some( + opus_projection_copy_channel_out_short + as unsafe fn( + *mut core::ffi::c_void, + i32, + i32, + *const opus_val16, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + frame_size, + decode_fec, + 1, + get_dec_demixing_matrix(st) as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_projection_decode_float( + st: *mut OpusProjectionDecoder, + data: *const u8, + len: i32, + pcm: *mut f32, + frame_size: i32, + decode_fec: i32, +) -> i32 { + return opus_multistream_decode_native( + get_multistream_decoder(st), + data, + len, + pcm as *mut core::ffi::c_void, + Some( + opus_projection_copy_channel_out_float + as unsafe fn( + *mut core::ffi::c_void, + i32, + i32, + *const opus_val16, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + frame_size, + decode_fec, + 0, + get_dec_demixing_matrix(st) as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_projection_decoder_ctl_impl( + st: *mut OpusProjectionDecoder, + request: i32, + args: VarArgs, +) -> i32 { + let mut ret: i32 = OPUS_OK; + ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st), request, args); + return ret; +} +#[macro_export] +macro_rules! opus_projection_decoder_ctl { + ($st:expr, $request:expr, $($arg:expr),*) => { + $crate::opus_projection_decoder_ctl_impl($st, $request, $crate::varargs!($($arg),*)) + }; + ($st:expr, $request:expr) => { + opus_projection_decoder_ctl!($st, $request,) + }; + ($st:expr, $request:expr, $($arg:expr),*,) => { + opus_projection_decoder_ctl!($st, $request, $($arg),*) + }; +} +pub unsafe fn opus_projection_decoder_destroy(st: *mut OpusProjectionDecoder) { + free(st as *mut core::ffi::c_void); +} diff --git a/vendor/unsafe-libopus/src/src/opus_projection_encoder.rs b/vendor/unsafe-libopus/src/src/opus_projection_encoder.rs new file mode 100644 index 00000000..41f1a8d2 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/opus_projection_encoder.rs @@ -0,0 +1,554 @@ +use crate::externs::{free, malloc}; +use crate::src::opus_encoder::{downmix_float, downmix_int}; +use crate::src::opus_multistream_encoder::{ + opus_multistream_encode_native, opus_multistream_encoder_ctl_va_list, +}; +use crate::src::opus_private::align; +use crate::{opus_multistream_encoder_get_size, opus_multistream_encoder_init, OpusMSEncoder}; + +pub mod arch_h { + pub type opus_val16 = f32; + pub type opus_val32 = f32; +} +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} +pub mod opus_projection_h { + pub const OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST: i32 = 6001; + pub const OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST: i32 = 6003; + pub const OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST: i32 = 6005; +} +pub use self::arch_h::{opus_val16, opus_val32}; +pub use self::opus_projection_h::{ + OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, + OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, +}; +pub use self::stddef_h::{size_t, NULL}; +use crate::celt::mathops::isqrt32; +use crate::src::mapping_matrix::{ + mapping_matrix_foa_demixing, mapping_matrix_foa_demixing_data, mapping_matrix_foa_mixing, + mapping_matrix_foa_mixing_data, mapping_matrix_get_data, mapping_matrix_get_size, + mapping_matrix_init, mapping_matrix_multiply_channel_in_float, + mapping_matrix_multiply_channel_in_short, mapping_matrix_soa_demixing, + mapping_matrix_soa_demixing_data, mapping_matrix_soa_mixing, mapping_matrix_soa_mixing_data, + mapping_matrix_toa_demixing, mapping_matrix_toa_demixing_data, mapping_matrix_toa_mixing, + mapping_matrix_toa_mixing_data, MappingMatrix, +}; +use crate::src::opus_defines::{OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_OK, OPUS_UNIMPLEMENTED}; +use crate::varargs::VarArgs; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusProjectionEncoder { + pub mixing_matrix_size_in_bytes: i32, + pub demixing_matrix_size_in_bytes: i32, +} +unsafe fn opus_projection_copy_channel_in_float( + dst: *mut opus_val16, + dst_stride: i32, + src: *const core::ffi::c_void, + src_stride: i32, + src_channel: i32, + frame_size: i32, + user_data: *mut core::ffi::c_void, +) { + mapping_matrix_multiply_channel_in_float( + user_data as *const MappingMatrix, + src as *const f32, + src_stride, + dst, + src_channel, + dst_stride, + frame_size, + ); +} +unsafe fn opus_projection_copy_channel_in_short( + dst: *mut opus_val16, + dst_stride: i32, + src: *const core::ffi::c_void, + src_stride: i32, + src_channel: i32, + frame_size: i32, + user_data: *mut core::ffi::c_void, +) { + mapping_matrix_multiply_channel_in_short( + user_data as *const MappingMatrix, + src as *const i16, + src_stride, + dst, + src_channel, + dst_stride, + frame_size, + ); +} +unsafe fn get_order_plus_one_from_channels(channels: i32, order_plus_one: *mut i32) -> i32 { + let mut order_plus_one_: i32 = 0; + let mut acn_channels: i32 = 0; + let mut nondiegetic_channels: i32 = 0; + if channels < 1 || channels > 227 { + return OPUS_BAD_ARG; + } + order_plus_one_ = isqrt32(channels as u32) as i32; + acn_channels = order_plus_one_ * order_plus_one_; + nondiegetic_channels = channels - acn_channels; + if nondiegetic_channels != 0 && nondiegetic_channels != 2 { + return OPUS_BAD_ARG; + } + if !order_plus_one.is_null() { + *order_plus_one = order_plus_one_; + } + return OPUS_OK; +} +unsafe fn get_streams_from_channels( + channels: i32, + mapping_family: i32, + streams: *mut i32, + coupled_streams: *mut i32, + order_plus_one: *mut i32, +) -> i32 { + if mapping_family == 3 { + if get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK { + return OPUS_BAD_ARG; + } + if !streams.is_null() { + *streams = (channels + 1) / 2; + } + if !coupled_streams.is_null() { + *coupled_streams = channels / 2; + } + return OPUS_OK; + } + return OPUS_BAD_ARG; +} +unsafe fn get_mixing_matrix(st: *mut OpusProjectionEncoder) -> *mut MappingMatrix { + return (st as *mut i8) + .offset(align(::core::mem::size_of::() as u64 as i32) as isize) + as *mut core::ffi::c_void as *mut MappingMatrix; +} +unsafe fn get_enc_demixing_matrix(st: *mut OpusProjectionEncoder) -> *mut MappingMatrix { + return (st as *mut i8).offset(align( + (::core::mem::size_of::() as u64) + .wrapping_add((*st).mixing_matrix_size_in_bytes as u64) as i32, + ) as isize) as *mut core::ffi::c_void as *mut MappingMatrix; +} +unsafe fn get_multistream_encoder(st: *mut OpusProjectionEncoder) -> *mut OpusMSEncoder { + return (st as *mut i8).offset(align( + (::core::mem::size_of::() as u64) + .wrapping_add((*st).mixing_matrix_size_in_bytes as u64) + .wrapping_add((*st).demixing_matrix_size_in_bytes as u64) as i32, + ) as isize) as *mut core::ffi::c_void as *mut OpusMSEncoder; +} +pub unsafe fn opus_projection_ambisonics_encoder_get_size( + channels: i32, + mapping_family: i32, +) -> i32 { + let mut nb_streams: i32 = 0; + let mut nb_coupled_streams: i32 = 0; + let mut order_plus_one: i32 = 0; + let mut mixing_matrix_rows: i32 = 0; + let mut mixing_matrix_cols: i32 = 0; + let mut demixing_matrix_rows: i32 = 0; + let mut demixing_matrix_cols: i32 = 0; + let mut mixing_matrix_size: i32 = 0; + let mut demixing_matrix_size: i32 = 0; + let mut encoder_size: i32 = 0; + let mut ret: i32 = 0; + ret = get_streams_from_channels( + channels, + mapping_family, + &mut nb_streams, + &mut nb_coupled_streams, + &mut order_plus_one, + ); + if ret != OPUS_OK { + return 0; + } + if order_plus_one == 2 { + mixing_matrix_rows = mapping_matrix_foa_mixing.rows; + mixing_matrix_cols = mapping_matrix_foa_mixing.cols; + demixing_matrix_rows = mapping_matrix_foa_demixing.rows; + demixing_matrix_cols = mapping_matrix_foa_demixing.cols; + } else if order_plus_one == 3 { + mixing_matrix_rows = mapping_matrix_soa_mixing.rows; + mixing_matrix_cols = mapping_matrix_soa_mixing.cols; + demixing_matrix_rows = mapping_matrix_soa_demixing.rows; + demixing_matrix_cols = mapping_matrix_soa_demixing.cols; + } else if order_plus_one == 4 { + mixing_matrix_rows = mapping_matrix_toa_mixing.rows; + mixing_matrix_cols = mapping_matrix_toa_mixing.cols; + demixing_matrix_rows = mapping_matrix_toa_demixing.rows; + demixing_matrix_cols = mapping_matrix_toa_demixing.cols; + } else { + return 0; + } + mixing_matrix_size = mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols); + if mixing_matrix_size == 0 { + return 0; + } + demixing_matrix_size = mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols); + if demixing_matrix_size == 0 { + return 0; + } + encoder_size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); + if encoder_size == 0 { + return 0; + } + return align(::core::mem::size_of::() as u64 as i32) + + mixing_matrix_size + + demixing_matrix_size + + encoder_size; +} +pub unsafe fn opus_projection_ambisonics_encoder_init( + st: *mut OpusProjectionEncoder, + Fs: i32, + channels: i32, + mapping_family: i32, + streams: *mut i32, + coupled_streams: *mut i32, + application: i32, +) -> i32 { + let mut mixing_matrix: *mut MappingMatrix = 0 as *mut MappingMatrix; + let mut demixing_matrix: *mut MappingMatrix = 0 as *mut MappingMatrix; + let mut ms_encoder: *mut OpusMSEncoder = 0 as *mut OpusMSEncoder; + let mut i: i32 = 0; + let mut ret: i32 = 0; + let mut order_plus_one: i32 = 0; + let mut mapping: [u8; 255] = [0; 255]; + if streams.is_null() || coupled_streams.is_null() { + return OPUS_BAD_ARG; + } + if get_streams_from_channels( + channels, + mapping_family, + streams, + coupled_streams, + &mut order_plus_one, + ) != OPUS_OK + { + return OPUS_BAD_ARG; + } + if mapping_family == 3 { + mixing_matrix = get_mixing_matrix(st); + if order_plus_one == 2 { + mapping_matrix_init( + mixing_matrix, + mapping_matrix_foa_mixing.rows, + mapping_matrix_foa_mixing.cols, + mapping_matrix_foa_mixing.gain, + mapping_matrix_foa_mixing_data.as_ptr(), + ::core::mem::size_of::<[i16; 36]>() as u64 as i32, + ); + } else if order_plus_one == 3 { + mapping_matrix_init( + mixing_matrix, + mapping_matrix_soa_mixing.rows, + mapping_matrix_soa_mixing.cols, + mapping_matrix_soa_mixing.gain, + mapping_matrix_soa_mixing_data.as_ptr(), + ::core::mem::size_of::<[i16; 121]>() as u64 as i32, + ); + } else if order_plus_one == 4 { + mapping_matrix_init( + mixing_matrix, + mapping_matrix_toa_mixing.rows, + mapping_matrix_toa_mixing.cols, + mapping_matrix_toa_mixing.gain, + mapping_matrix_toa_mixing_data.as_ptr(), + ::core::mem::size_of::<[i16; 324]>() as u64 as i32, + ); + } else { + return OPUS_BAD_ARG; + } + (*st).mixing_matrix_size_in_bytes = + mapping_matrix_get_size((*mixing_matrix).rows, (*mixing_matrix).cols); + if (*st).mixing_matrix_size_in_bytes == 0 { + return OPUS_BAD_ARG; + } + demixing_matrix = get_enc_demixing_matrix(st); + if order_plus_one == 2 { + mapping_matrix_init( + demixing_matrix, + mapping_matrix_foa_demixing.rows, + mapping_matrix_foa_demixing.cols, + mapping_matrix_foa_demixing.gain, + mapping_matrix_foa_demixing_data.as_ptr(), + ::core::mem::size_of::<[i16; 36]>() as u64 as i32, + ); + } else if order_plus_one == 3 { + mapping_matrix_init( + demixing_matrix, + mapping_matrix_soa_demixing.rows, + mapping_matrix_soa_demixing.cols, + mapping_matrix_soa_demixing.gain, + mapping_matrix_soa_demixing_data.as_ptr(), + ::core::mem::size_of::<[i16; 121]>() as u64 as i32, + ); + } else if order_plus_one == 4 { + mapping_matrix_init( + demixing_matrix, + mapping_matrix_toa_demixing.rows, + mapping_matrix_toa_demixing.cols, + mapping_matrix_toa_demixing.gain, + mapping_matrix_toa_demixing_data.as_ptr(), + ::core::mem::size_of::<[i16; 324]>() as u64 as i32, + ); + } else { + return OPUS_BAD_ARG; + } + (*st).demixing_matrix_size_in_bytes = + mapping_matrix_get_size((*demixing_matrix).rows, (*demixing_matrix).cols); + if (*st).demixing_matrix_size_in_bytes == 0 { + return OPUS_BAD_ARG; + } + } else { + return OPUS_UNIMPLEMENTED; + } + if *streams + *coupled_streams > (*mixing_matrix).rows + || channels > (*mixing_matrix).cols + || channels > (*demixing_matrix).rows + || *streams + *coupled_streams > (*demixing_matrix).cols + { + return OPUS_BAD_ARG; + } + i = 0; + while i < channels { + mapping[i as usize] = i as u8; + i += 1; + } + ms_encoder = get_multistream_encoder(st); + ret = opus_multistream_encoder_init( + ms_encoder, + Fs, + channels, + *streams, + *coupled_streams, + mapping.as_mut_ptr(), + application, + ); + return ret; +} +pub unsafe fn opus_projection_ambisonics_encoder_create( + Fs: i32, + channels: i32, + mapping_family: i32, + streams: *mut i32, + coupled_streams: *mut i32, + application: i32, + error: *mut i32, +) -> *mut OpusProjectionEncoder { + let mut size: i32 = 0; + let mut ret: i32 = 0; + let mut st: *mut OpusProjectionEncoder = 0 as *mut OpusProjectionEncoder; + size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family); + if size == 0 { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusProjectionEncoder; + } + st = malloc(size as size_t) as *mut OpusProjectionEncoder; + if st.is_null() { + if !error.is_null() { + *error = OPUS_ALLOC_FAIL; + } + return NULL as *mut OpusProjectionEncoder; + } + ret = opus_projection_ambisonics_encoder_init( + st, + Fs, + channels, + mapping_family, + streams, + coupled_streams, + application, + ); + if ret != OPUS_OK { + free(st as *mut core::ffi::c_void); + st = NULL as *mut OpusProjectionEncoder; + } + if !error.is_null() { + *error = ret; + } + return st; +} +pub unsafe fn opus_projection_encode( + st: *mut OpusProjectionEncoder, + pcm: *const i16, + frame_size: i32, + data: *mut u8, + max_data_bytes: i32, +) -> i32 { + return opus_multistream_encode_native( + get_multistream_encoder(st), + Some( + opus_projection_copy_channel_in_short + as unsafe fn( + *mut opus_val16, + i32, + *const core::ffi::c_void, + i32, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + pcm as *const core::ffi::c_void, + frame_size, + data, + max_data_bytes, + 16, + Some( + downmix_int + as unsafe fn( + *const core::ffi::c_void, + *mut opus_val32, + i32, + i32, + i32, + i32, + i32, + ) -> (), + ), + 0, + get_mixing_matrix(st) as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_projection_encode_float( + st: *mut OpusProjectionEncoder, + pcm: *const f32, + frame_size: i32, + data: *mut u8, + max_data_bytes: i32, +) -> i32 { + return opus_multistream_encode_native( + get_multistream_encoder(st), + Some( + opus_projection_copy_channel_in_float + as unsafe fn( + *mut opus_val16, + i32, + *const core::ffi::c_void, + i32, + i32, + i32, + *mut core::ffi::c_void, + ) -> (), + ), + pcm as *const core::ffi::c_void, + frame_size, + data, + max_data_bytes, + 24, + Some( + downmix_float + as unsafe fn( + *const core::ffi::c_void, + *mut opus_val32, + i32, + i32, + i32, + i32, + i32, + ) -> (), + ), + 1, + get_mixing_matrix(st) as *mut core::ffi::c_void, + ); +} +pub unsafe fn opus_projection_encoder_destroy(st: *mut OpusProjectionEncoder) { + free(st as *mut core::ffi::c_void); +} +pub unsafe fn opus_projection_encoder_ctl_impl( + st: *mut OpusProjectionEncoder, + request: i32, + args: VarArgs, +) -> i32 { + let current_block: u64; + let mut demixing_matrix: *mut MappingMatrix = 0 as *mut MappingMatrix; + let mut ms_encoder: *mut OpusMSEncoder = 0 as *mut OpusMSEncoder; + let mut ret: i32 = OPUS_OK; + ms_encoder = get_multistream_encoder(st); + demixing_matrix = get_enc_demixing_matrix(st); + let mut ap = args; + match request { + OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST => { + let value = ap.arg::<&mut i32>(); + *value = (((*ms_encoder).layout.nb_channels + * ((*ms_encoder).layout.nb_streams + (*ms_encoder).layout.nb_coupled_streams)) + as u64) + .wrapping_mul(::core::mem::size_of::() as u64) as i32; + current_block = 18153031941552419006; + } + OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST => { + let value_0 = ap.arg::<&mut i32>(); + *value_0 = (*demixing_matrix).gain; + current_block = 18153031941552419006; + } + OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST => { + let mut i: i32 = 0; + let mut j: i32 = 0; + let mut k: i32 = 0; + let mut l: i32 = 0; + let mut nb_input_streams: i32 = 0; + let mut nb_output_streams: i32 = 0; + let mut external_char: *mut u8 = 0 as *mut u8; + let mut internal_short: *mut i16 = 0 as *mut i16; + let mut external_size: i32 = 0; + let mut internal_size: i32 = 0; + nb_input_streams = + (*ms_encoder).layout.nb_streams + (*ms_encoder).layout.nb_coupled_streams; + nb_output_streams = (*ms_encoder).layout.nb_channels; + external_char = ap.arg::<*mut u8>(); + external_size = ap.arg::(); + if external_char.is_null() { + current_block = 17184638872671510253; + } else { + internal_short = mapping_matrix_get_data(demixing_matrix); + internal_size = ((nb_input_streams * nb_output_streams) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + as i32; + if external_size != internal_size { + current_block = 17184638872671510253; + } else { + l = 0; + i = 0; + while i < nb_input_streams { + j = 0; + while j < nb_output_streams { + k = (*demixing_matrix).rows * i + j; + *external_char.offset((2 * l) as isize) = + *internal_short.offset(k as isize) as u8; + *external_char.offset((2 * l + 1) as isize) = + (*internal_short.offset(k as isize) as i32 >> 8) as u8; + l += 1; + j += 1; + } + i += 1; + } + current_block = 18153031941552419006; + } + } + } + _ => { + ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap); + current_block = 18153031941552419006; + } + } + match current_block { + 17184638872671510253 => return OPUS_BAD_ARG, + _ => return ret, + }; +} +#[macro_export] +macro_rules! opus_projection_encoder_ctl { + ($st:expr, $request:expr, $($arg:expr),*) => { + $crate::opus_projection_encoder_ctl_impl($st, $request, $crate::varargs!($($arg),*)) + }; + ($st:expr, $request:expr) => { + opus_projection_encoder_ctl!($st, $request,) + }; + ($st:expr, $request:expr, $($arg:expr),*,) => { + opus_projection_encoder_ctl!($st, $request, $($arg),*) + }; +} diff --git a/vendor/unsafe-libopus/src/src/repacketizer.rs b/vendor/unsafe-libopus/src/src/repacketizer.rs new file mode 100644 index 00000000..48fb46a6 --- /dev/null +++ b/vendor/unsafe-libopus/src/src/repacketizer.rs @@ -0,0 +1,435 @@ +use crate::externs::{free, malloc}; +#[derive(Copy, Clone)] +#[repr(C)] +pub struct OpusRepacketizer { + pub(crate) toc: u8, + pub(crate) nb_frames: i32, + pub(crate) frames: [*const u8; 48], + pub(crate) len: [i16; 48], + pub(crate) framesize: i32, +} + +pub mod stddef_h { + pub type size_t = u64; + pub const NULL: i32 = 0; +} +pub use self::stddef_h::{size_t, NULL}; +use crate::src::opus_defines::{OPUS_BAD_ARG, OPUS_BUFFER_TOO_SMALL, OPUS_INVALID_PACKET, OPUS_OK}; + +use crate::externs::memmove; +use crate::src::opus::{encode_size, opus_packet_parse_impl}; +use crate::{opus_packet_get_nb_frames, opus_packet_get_samples_per_frame}; + +pub unsafe fn opus_repacketizer_get_size() -> i32 { + return ::core::mem::size_of::() as u64 as i32; +} +pub unsafe fn opus_repacketizer_init(rp: *mut OpusRepacketizer) -> *mut OpusRepacketizer { + (*rp).nb_frames = 0; + return rp; +} +pub unsafe fn opus_repacketizer_create() -> *mut OpusRepacketizer { + let mut rp: *mut OpusRepacketizer = 0 as *mut OpusRepacketizer; + rp = malloc(opus_repacketizer_get_size() as size_t) as *mut OpusRepacketizer; + if rp.is_null() { + return NULL as *mut OpusRepacketizer; + } + return opus_repacketizer_init(rp); +} +pub unsafe fn opus_repacketizer_destroy(rp: *mut OpusRepacketizer) { + free(rp as *mut core::ffi::c_void); +} +unsafe fn opus_repacketizer_cat_impl( + rp: *mut OpusRepacketizer, + data: *const u8, + len: i32, + self_delimited: i32, +) -> i32 { + let mut tmp_toc: u8 = 0; + let mut curr_nb_frames: i32 = 0; + let mut ret: i32 = 0; + if len < 1 { + return OPUS_INVALID_PACKET; + } + if (*rp).nb_frames == 0 { + (*rp).toc = *data.offset(0 as isize); + (*rp).framesize = opus_packet_get_samples_per_frame(data, 8000); + } else if (*rp).toc as i32 & 0xfc != *data.offset(0 as isize) as i32 & 0xfc { + return OPUS_INVALID_PACKET; + } + curr_nb_frames = opus_packet_get_nb_frames(data, len); + if curr_nb_frames < 1 { + return OPUS_INVALID_PACKET; + } + if (curr_nb_frames + (*rp).nb_frames) * (*rp).framesize > 960 { + return OPUS_INVALID_PACKET; + } + ret = opus_packet_parse_impl( + data, + len, + self_delimited, + &mut tmp_toc, + &mut *((*rp).frames).as_mut_ptr().offset((*rp).nb_frames as isize), + &mut *((*rp).len).as_mut_ptr().offset((*rp).nb_frames as isize), + NULL as *mut i32, + NULL as *mut i32, + ); + if ret < 1 { + return ret; + } + (*rp).nb_frames += curr_nb_frames; + return OPUS_OK; +} +pub unsafe fn opus_repacketizer_cat(rp: *mut OpusRepacketizer, data: *const u8, len: i32) -> i32 { + return opus_repacketizer_cat_impl(rp, data, len, 0); +} +pub unsafe fn opus_repacketizer_get_nb_frames(rp: *mut OpusRepacketizer) -> i32 { + return (*rp).nb_frames; +} +pub unsafe fn opus_repacketizer_out_range_impl( + rp: *mut OpusRepacketizer, + begin: i32, + end: i32, + data: *mut u8, + maxlen: i32, + self_delimited: i32, + pad: i32, +) -> i32 { + let mut i: i32 = 0; + let mut count: i32 = 0; + let mut tot_size: i32 = 0; + let mut len: *mut i16 = 0 as *mut i16; + let mut frames: *mut *const u8 = 0 as *mut *const u8; + let mut ptr: *mut u8 = 0 as *mut u8; + if begin < 0 || begin >= end || end > (*rp).nb_frames { + return OPUS_BAD_ARG; + } + count = end - begin; + len = ((*rp).len).as_mut_ptr().offset(begin as isize); + frames = ((*rp).frames).as_mut_ptr().offset(begin as isize); + if self_delimited != 0 { + tot_size = 1 + (*len.offset((count - 1) as isize) as i32 >= 252) as i32; + } else { + tot_size = 0; + } + ptr = data; + if count == 1 { + tot_size += *len.offset(0 as isize) as i32 + 1; + if tot_size > maxlen { + return OPUS_BUFFER_TOO_SMALL; + } + let fresh0 = ptr; + ptr = ptr.offset(1); + *fresh0 = ((*rp).toc as i32 & 0xfc) as u8; + } else if count == 2 { + if *len.offset(1 as isize) as i32 == *len.offset(0 as isize) as i32 { + tot_size += 2 * *len.offset(0 as isize) as i32 + 1; + if tot_size > maxlen { + return OPUS_BUFFER_TOO_SMALL; + } + let fresh1 = ptr; + ptr = ptr.offset(1); + *fresh1 = ((*rp).toc as i32 & 0xfc | 0x1) as u8; + } else { + tot_size += *len.offset(0 as isize) as i32 + + *len.offset(1 as isize) as i32 + + 2 + + (*len.offset(0 as isize) as i32 >= 252) as i32; + if tot_size > maxlen { + return OPUS_BUFFER_TOO_SMALL; + } + let fresh2 = ptr; + ptr = ptr.offset(1); + *fresh2 = ((*rp).toc as i32 & 0xfc | 0x2) as u8; + ptr = ptr.offset(encode_size(*len.offset(0 as isize) as i32, ptr) as isize); + } + } + if count > 2 || pad != 0 && tot_size < maxlen { + let mut vbr: i32 = 0; + let mut pad_amount: i32 = 0; + ptr = data; + if self_delimited != 0 { + tot_size = 1 + (*len.offset((count - 1) as isize) as i32 >= 252) as i32; + } else { + tot_size = 0; + } + vbr = 0; + i = 1; + while i < count { + if *len.offset(i as isize) as i32 != *len.offset(0 as isize) as i32 { + vbr = 1; + break; + } else { + i += 1; + } + } + if vbr != 0 { + tot_size += 2; + i = 0; + while i < count - 1 { + tot_size += 1 + + (*len.offset(i as isize) as i32 >= 252) as i32 + + *len.offset(i as isize) as i32; + i += 1; + } + tot_size += *len.offset((count - 1) as isize) as i32; + if tot_size > maxlen { + return OPUS_BUFFER_TOO_SMALL; + } + let fresh3 = ptr; + ptr = ptr.offset(1); + *fresh3 = ((*rp).toc as i32 & 0xfc | 0x3) as u8; + let fresh4 = ptr; + ptr = ptr.offset(1); + *fresh4 = (count | 0x80) as u8; + } else { + tot_size += count * *len.offset(0 as isize) as i32 + 2; + if tot_size > maxlen { + return OPUS_BUFFER_TOO_SMALL; + } + let fresh5 = ptr; + ptr = ptr.offset(1); + *fresh5 = ((*rp).toc as i32 & 0xfc | 0x3) as u8; + let fresh6 = ptr; + ptr = ptr.offset(1); + *fresh6 = count as u8; + } + pad_amount = if pad != 0 { maxlen - tot_size } else { 0 }; + if pad_amount != 0 { + let mut nb_255s: i32 = 0; + let ref mut fresh7 = *data.offset(1 as isize); + *fresh7 = (*fresh7 as i32 | 0x40) as u8; + nb_255s = (pad_amount - 1) / 255; + i = 0; + while i < nb_255s { + let fresh8 = ptr; + ptr = ptr.offset(1); + *fresh8 = 255; + i += 1; + } + let fresh9 = ptr; + ptr = ptr.offset(1); + *fresh9 = (pad_amount - 255 * nb_255s - 1) as u8; + tot_size += pad_amount; + } + if vbr != 0 { + i = 0; + while i < count - 1 { + ptr = ptr.offset(encode_size(*len.offset(i as isize) as i32, ptr) as isize); + i += 1; + } + } + } + if self_delimited != 0 { + let sdlen: i32 = encode_size(*len.offset((count - 1) as isize) as i32, ptr); + ptr = ptr.offset(sdlen as isize); + } + i = 0; + while i < count { + memmove( + ptr as *mut core::ffi::c_void, + *frames.offset(i as isize) as *const core::ffi::c_void, + (*len.offset(i as isize) as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add((0 * ptr.offset_from(*frames.offset(i as isize)) as i64) as u64), + ); + ptr = ptr.offset(*len.offset(i as isize) as i32 as isize); + i += 1; + } + if pad != 0 { + while ptr < data.offset(maxlen as isize) { + let fresh10 = ptr; + ptr = ptr.offset(1); + *fresh10 = 0; + } + } + return tot_size; +} +pub unsafe fn opus_repacketizer_out_range( + rp: *mut OpusRepacketizer, + begin: i32, + end: i32, + data: *mut u8, + maxlen: i32, +) -> i32 { + return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0, 0); +} +pub unsafe fn opus_repacketizer_out(rp: *mut OpusRepacketizer, data: *mut u8, maxlen: i32) -> i32 { + return opus_repacketizer_out_range_impl(rp, 0, (*rp).nb_frames, data, maxlen, 0, 0); +} +pub unsafe fn opus_packet_pad(data: *mut u8, len: i32, new_len: i32) -> i32 { + let mut rp: OpusRepacketizer = OpusRepacketizer { + toc: 0, + nb_frames: 0, + frames: [0 as *const u8; 48], + len: [0; 48], + framesize: 0, + }; + let mut ret: i32 = 0; + if len < 1 { + return OPUS_BAD_ARG; + } + if len == new_len { + return OPUS_OK; + } else { + if len > new_len { + return OPUS_BAD_ARG; + } + } + opus_repacketizer_init(&mut rp); + memmove( + data.offset(new_len as isize).offset(-(len as isize)) as *mut core::ffi::c_void, + data as *const core::ffi::c_void, + (len as u64) + .wrapping_mul(::core::mem::size_of::() as u64) + .wrapping_add( + (0 * data + .offset(new_len as isize) + .offset(-(len as isize)) + .offset_from(data) as i64) as u64, + ), + ); + ret = opus_repacketizer_cat( + &mut rp, + data.offset(new_len as isize).offset(-(len as isize)), + len, + ); + if ret != OPUS_OK { + return ret; + } + ret = opus_repacketizer_out_range_impl(&mut rp, 0, rp.nb_frames, data, new_len, 0, 1); + if ret > 0 { + return OPUS_OK; + } else { + return ret; + }; +} +pub unsafe fn opus_packet_unpad(data: *mut u8, len: i32) -> i32 { + let mut rp: OpusRepacketizer = OpusRepacketizer { + toc: 0, + nb_frames: 0, + frames: [0 as *const u8; 48], + len: [0; 48], + framesize: 0, + }; + let mut ret: i32 = 0; + if len < 1 { + return OPUS_BAD_ARG; + } + opus_repacketizer_init(&mut rp); + ret = opus_repacketizer_cat(&mut rp, data, len); + if ret < 0 { + return ret; + } + ret = opus_repacketizer_out_range_impl(&mut rp, 0, rp.nb_frames, data, len, 0, 0); + assert!(ret > 0 && ret <= len); + return ret; +} +pub unsafe fn opus_multistream_packet_pad( + mut data: *mut u8, + mut len: i32, + new_len: i32, + nb_streams: i32, +) -> i32 { + let mut s: i32 = 0; + let mut count: i32 = 0; + let mut toc: u8 = 0; + let mut size: [i16; 48] = [0; 48]; + let mut packet_offset: i32 = 0; + let mut amount: i32 = 0; + if len < 1 { + return OPUS_BAD_ARG; + } + if len == new_len { + return OPUS_OK; + } else { + if len > new_len { + return OPUS_BAD_ARG; + } + } + amount = new_len - len; + s = 0; + while s < nb_streams - 1 { + if len <= 0 { + return OPUS_INVALID_PACKET; + } + count = opus_packet_parse_impl( + data, + len, + 1, + &mut toc, + NULL as *mut *const u8, + size.as_mut_ptr(), + NULL as *mut i32, + &mut packet_offset, + ); + if count < 0 { + return count; + } + data = data.offset(packet_offset as isize); + len -= packet_offset; + s += 1; + } + return opus_packet_pad(data, len, len + amount); +} +pub unsafe fn opus_multistream_packet_unpad( + mut data: *mut u8, + mut len: i32, + nb_streams: i32, +) -> i32 { + let mut s: i32 = 0; + let mut toc: u8 = 0; + let mut size: [i16; 48] = [0; 48]; + let mut packet_offset: i32 = 0; + let mut rp: OpusRepacketizer = OpusRepacketizer { + toc: 0, + nb_frames: 0, + frames: [0 as *const u8; 48], + len: [0; 48], + framesize: 0, + }; + let mut dst: *mut u8 = 0 as *mut u8; + let mut dst_len: i32 = 0; + if len < 1 { + return OPUS_BAD_ARG; + } + dst = data; + dst_len = 0; + s = 0; + while s < nb_streams { + let mut ret: i32 = 0; + let self_delimited: i32 = (s != nb_streams - 1) as i32; + if len <= 0 { + return OPUS_INVALID_PACKET; + } + opus_repacketizer_init(&mut rp); + ret = opus_packet_parse_impl( + data, + len, + self_delimited, + &mut toc, + NULL as *mut *const u8, + size.as_mut_ptr(), + NULL as *mut i32, + &mut packet_offset, + ); + if ret < 0 { + return ret; + } + ret = opus_repacketizer_cat_impl(&mut rp, data, packet_offset, self_delimited); + if ret < 0 { + return ret; + } + ret = + opus_repacketizer_out_range_impl(&mut rp, 0, rp.nb_frames, dst, len, self_delimited, 0); + if ret < 0 { + return ret; + } else { + dst_len += ret; + } + dst = dst.offset(ret as isize); + data = data.offset(packet_offset as isize); + len -= packet_offset; + s += 1; + } + return dst_len; +} diff --git a/vendor/unsafe-libopus/src/varargs.rs b/vendor/unsafe-libopus/src/varargs.rs new file mode 100644 index 00000000..f950ad29 --- /dev/null +++ b/vendor/unsafe-libopus/src/varargs.rs @@ -0,0 +1,92 @@ +//! A bit more type-safe variadic function APIs. Not really ABI-compatible with C, just a compat layer. + +pub enum VarArg<'a> { + I32(i32), + I32Out(&'a mut i32), + U32Out(&'a mut u32), + F32Ptr(*mut f32), + U8Ptr(*mut u8), + CustomModeOut(&'a mut *const crate::OpusCustomMode), + OpusDecoderOut(&'a mut *mut crate::OpusDecoder), + OpusEncoderOut(&'a mut *mut crate::OpusEncoder), + AnalysisInfoOut(&'a mut crate::src::analysis::AnalysisInfo), + SilkInfoOut(&'a mut crate::celt::celt_encoder::SILKInfo), +} + +pub trait FromVarArg<'a> { + fn from_vararg(arg: VarArg<'a>) -> Self; +} + +pub trait IntoVarArg<'a> { + fn into_vararg(self) -> VarArg<'a>; +} + +macro_rules! impl_from_vararg { + ($t:ty, $v:ident) => { + impl<'a> FromVarArg<'a> for $t { + fn from_vararg(arg: VarArg<'a>) -> Self { + match arg { + VarArg::$v(v) => v, + _ => panic!("invalid vararg type"), + } + } + } + }; +} +macro_rules! impl_into_vararg { + ($t:ty, $v:ident) => { + impl<'a> IntoVarArg<'a> for $t { + fn into_vararg(self) -> VarArg<'a> { + VarArg::$v(self) + } + } + }; +} +macro_rules! impl_vararg { + ($t:ty, $v:ident) => { + impl_from_vararg!($t, $v); + impl_into_vararg!($t, $v); + }; +} + +impl_vararg!(i32, I32); +impl_vararg!(&'a mut i32, I32Out); +impl_vararg!(&'a mut u32, U32Out); +impl_vararg!(*mut f32, F32Ptr); +impl_vararg!(*mut u8, U8Ptr); +impl_vararg!(&'a mut *const crate::OpusCustomMode, CustomModeOut); +impl_vararg!(&'a mut *mut crate::OpusDecoder, OpusDecoderOut); +impl_vararg!(&'a mut *mut crate::OpusEncoder, OpusEncoderOut); +impl_vararg!(&'a mut crate::src::analysis::AnalysisInfo, AnalysisInfoOut); +impl_vararg!(&'a mut crate::celt::celt_encoder::SILKInfo, SilkInfoOut); + +pub struct VarArgs<'a>(pub Vec>); + +impl<'a> VarArgs<'a> { + pub fn new(mut varargs: Vec>) -> Self { + // reverse them, because we pop them off the end, but want to have order "from left to right" + varargs.reverse(); + Self(varargs) + } + + pub fn arg>(&mut self) -> T { + T::from_vararg( + self.0 + .pop() + .expect("Attempt to pop from empty varargs (are the function arguments correct?)"), + ) + } +} + +#[macro_export] +macro_rules! varargs { + ($($arg:expr),*) => { + $crate::varargs::VarArgs::new( + vec![ + $( + $crate::varargs::IntoVarArg::into_vararg($arg) + ),* + ] + ) + }; +}