1use crate::celt::modes::OpusCustomMode;
2
3pub mod arch_h {
4 pub type opus_val16 = f32;
5 pub type opus_val32 = f32;
6}
7
8pub use self::arch_h::{opus_val16, opus_val32};
9use crate::externs::memmove;
10
11pub static trim_icdf: [u8; 11] = [126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0];
12pub static spread_icdf: [u8; 4] = [25, 23, 2, 0];
13pub static tapset_icdf: [u8; 3] = [2, 1, 0];
14pub static tf_select_table: [[i8; 8]; 4] = [
15 [0, -1, 0, -1, 0, -1, 0, -1],
16 [0, -1, 0, -2, 1, 0, 1, -1],
17 [0, -2, 0, -3, 2, 0, 1, -1],
18 [0, -2, 0, -3, 3, 0, 1, -1],
19];
20
21pub const OPUS_SET_ENERGY_MASK_REQUEST: i32 = 10026;
22pub const CELT_GET_MODE_REQUEST: i32 = 10015;
23pub const CELT_SET_SILK_INFO_REQUEST: i32 = 10028;
24pub const CELT_SET_ANALYSIS_REQUEST: i32 = 10022;
25pub const CELT_SET_SIGNALLING_REQUEST: i32 = 10016;
26pub const OPUS_SET_LFE_REQUEST: i32 = 10024;
27pub const CELT_SET_START_BAND_REQUEST: i32 = 10010;
28pub const CELT_SET_CHANNELS_REQUEST: i32 = 10008;
29pub const CELT_SET_END_BAND_REQUEST: i32 = 10012;
30pub const CELT_SET_PREDICTION_REQUEST: i32 = 10002;
31pub const CELT_GET_AND_CLEAR_ERROR_REQUEST: i32 = 10007;
32
33pub const COMBFILTER_MAXPERIOD: i32 = 1024;
34pub const COMBFILTER_MINPERIOD: i32 = 15;
35
36pub fn resampling_factor(rate: i32) -> i32 {
37 match rate {
38 48000 => 1,
39 24000 => 2,
40 16000 => 3,
41 12000 => 4,
42 8000 => 6,
43 _ => panic!("Unsupported sampling rate: {}", rate),
44 }
45}
46unsafe fn comb_filter_const_c(
47 y: *mut opus_val32,
48 x: *mut opus_val32,
49 T: i32,
50 N: i32,
51 g10: opus_val16,
52 g11: opus_val16,
53 g12: opus_val16,
54) {
55 let mut x0: opus_val32 = 0.;
56 let mut x1: opus_val32 = 0.;
57 let mut x2: opus_val32 = 0.;
58 let mut x3: opus_val32 = 0.;
59 let mut x4: opus_val32 = 0.;
60 let mut i: i32 = 0;
61 x4 = *x.offset((-T - 2) as isize);
62 x3 = *x.offset((-T - 1) as isize);
63 x2 = *x.offset(-T as isize);
64 x1 = *x.offset((-T + 1) as isize);
65 i = 0;
66 while i < N {
67 x0 = *x.offset((i - T + 2) as isize);
68 *y.offset(i as isize) =
69 *x.offset(i as isize) + g10 * x2 + g11 * (x1 + x3) + g12 * (x0 + x4);
70 *y.offset(i as isize) = *y.offset(i as isize);
71 x4 = x3;
72 x3 = x2;
73 x2 = x1;
74 x1 = x0;
75 i += 1;
76 }
77}
78pub unsafe fn comb_filter(
79 y: *mut opus_val32,
80 x: *mut opus_val32,
81 mut T0: i32,
82 mut T1: i32,
83 N: i32,
84 g0: opus_val16,
85 g1: opus_val16,
86 tapset0: i32,
87 tapset1: i32,
88 window: *const opus_val16,
89 mut overlap: i32,
90 _arch: i32,
91) {
92 let mut i: i32 = 0;
93 let mut g00: opus_val16 = 0.;
94 let mut g01: opus_val16 = 0.;
95 let mut g02: opus_val16 = 0.;
96 let mut g10: opus_val16 = 0.;
97 let mut g11: opus_val16 = 0.;
98 let mut g12: opus_val16 = 0.;
99 let mut x0: opus_val32 = 0.;
100 let mut x1: opus_val32 = 0.;
101 let mut x2: opus_val32 = 0.;
102 let mut x3: opus_val32 = 0.;
103 let mut x4: opus_val32 = 0.;
104 static mut gains: [[opus_val16; 3]; 3] = [
105 [0.3066406250f32, 0.2170410156f32, 0.1296386719f32],
106 [0.4638671875f32, 0.2680664062f32, 0.0f32],
107 [0.7998046875f32, 0.1000976562f32, 0.0f32],
108 ];
109 if g0 == 0 as f32 && g1 == 0 as f32 {
110 if x != y {
111 memmove(
112 y as *mut core::ffi::c_void,
113 x as *const core::ffi::c_void,
114 (N as u64)
115 .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
116 .wrapping_add((0 * y.offset_from(x) as i64) as u64),
117 );
118 }
119 return;
120 }
121 T0 = if T0 > 15 { T0 } else { 15 };
122 T1 = if T1 > 15 { T1 } else { 15 };
123 g00 = g0 * gains[tapset0 as usize][0 as usize];
124 g01 = g0 * gains[tapset0 as usize][1 as usize];
125 g02 = g0 * gains[tapset0 as usize][2 as usize];
126 g10 = g1 * gains[tapset1 as usize][0 as usize];
127 g11 = g1 * gains[tapset1 as usize][1 as usize];
128 g12 = g1 * gains[tapset1 as usize][2 as usize];
129 x1 = *x.offset((-T1 + 1) as isize);
130 x2 = *x.offset(-T1 as isize);
131 x3 = *x.offset((-T1 - 1) as isize);
132 x4 = *x.offset((-T1 - 2) as isize);
133 if g0 == g1 && T0 == T1 && tapset0 == tapset1 {
134 overlap = 0;
135 }
136 i = 0;
137 while i < overlap {
138 let mut f: opus_val16 = 0.;
139 x0 = *x.offset((i - T1 + 2) as isize);
140 f = *window.offset(i as isize) * *window.offset(i as isize);
141 *y.offset(i as isize) = *x.offset(i as isize)
142 + (1.0f32 - f) * g00 * *x.offset((i - T0) as isize)
143 + (1.0f32 - f)
144 * g01
145 * (*x.offset((i - T0 + 1) as isize) + *x.offset((i - T0 - 1) as isize))
146 + (1.0f32 - f)
147 * g02
148 * (*x.offset((i - T0 + 2) as isize) + *x.offset((i - T0 - 2) as isize))
149 + f * g10 * x2
150 + f * g11 * (x1 + x3)
151 + f * g12 * (x0 + x4);
152 *y.offset(i as isize) = *y.offset(i as isize);
153 x4 = x3;
154 x3 = x2;
155 x2 = x1;
156 x1 = x0;
157 i += 1;
158 }
159 if g1 == 0 as f32 {
160 if x != y {
161 memmove(
162 y.offset(overlap as isize) as *mut core::ffi::c_void,
163 x.offset(overlap as isize) as *const core::ffi::c_void,
164 ((N - overlap) as u64)
165 .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
166 .wrapping_add(
167 (0 * y
168 .offset(overlap as isize)
169 .offset_from(x.offset(overlap as isize))
170 as i64) as u64,
171 ),
172 );
173 }
174 return;
175 }
176 comb_filter_const_c(
177 y.offset(i as isize),
178 x.offset(i as isize),
179 T1,
180 N - i,
181 g10,
182 g11,
183 g12,
184 );
185}
186pub unsafe fn init_caps(m: *const OpusCustomMode, cap: *mut i32, LM: i32, C: i32) {
187 let mut i: i32 = 0;
188 i = 0;
189 while i < (*m).nbEBands {
190 let mut N: i32 = 0;
191 N = (*((*m).eBands).offset((i + 1) as isize) as i32
192 - *((*m).eBands).offset(i as isize) as i32)
193 << LM;
194 *cap.offset(i as isize) =
195 (*((*m).cache.caps).offset(((*m).nbEBands * (2 * LM + C - 1) + i) as isize) as i32
196 + 64)
197 * C
198 * N
199 >> 2;
200 i += 1;
201 }
202}
203
204pub fn opus_strerror(error: i32) -> &'static str {
205 static error_strings: [&str; 8] = [
206 "success (0)",
207 "invalid argument (-1)",
208 "buffer too small (-2)",
209 "internal error (-3)",
210 "corrupted stream (-4)",
211 "request not implemented (-5)",
212 "invalid state (-6)",
213 "memory allocation failed (-7)",
214 ];
215 if error > 0 || error < -7 {
216 "unknown error"
217 } else {
218 error_strings[-error as usize]
219 }
220}
221
222pub fn opus_get_version_string() -> &'static str {
223 "unsafe-libopus (rust port) 1.3.1"
224}