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 e87ddfc1..f6302ac8 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/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); 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) + ),* + ] + ) + }; +}