1use crate::externs::{free, malloc};
2
3pub mod arch_h {
4 pub type opus_val16 = f32;
5}
6pub mod stddef_h {
7 pub type size_t = u64;
8 pub const NULL: i32 = 0;
9}
10pub use self::arch_h::opus_val16;
11pub use self::stddef_h::{size_t, NULL};
12use crate::src::opus_defines::{OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_OK};
13
14use crate::externs::memset;
15use crate::src::mapping_matrix::{
16 mapping_matrix_get_size, mapping_matrix_init, mapping_matrix_multiply_channel_out_float,
17 mapping_matrix_multiply_channel_out_short, MappingMatrix,
18};
19use crate::src::opus_multistream_decoder::{
20 opus_multistream_decode_native, opus_multistream_decoder_ctl_va_list,
21};
22use crate::src::opus_private::align;
23use crate::varargs::VarArgs;
24use crate::{opus_multistream_decoder_get_size, opus_multistream_decoder_init, OpusMSDecoder};
25
26#[derive(Copy, Clone)]
27#[repr(C)]
28pub struct OpusProjectionDecoder {
29 pub demixing_matrix_size_in_bytes: i32,
30}
31unsafe fn opus_projection_copy_channel_out_float(
32 dst: *mut core::ffi::c_void,
33 dst_stride: i32,
34 dst_channel: i32,
35 src: *const opus_val16,
36 src_stride: i32,
37 frame_size: i32,
38 user_data: *mut core::ffi::c_void,
39) {
40 let mut float_dst: *mut f32 = 0 as *mut f32;
41 let mut matrix: *const MappingMatrix = 0 as *const MappingMatrix;
42 float_dst = dst as *mut f32;
43 matrix = user_data as *const MappingMatrix;
44 if dst_channel == 0 {
45 memset(
46 float_dst as *mut core::ffi::c_void,
47 0,
48 ((frame_size * dst_stride) as u64).wrapping_mul(::core::mem::size_of::<f32>() as u64),
49 );
50 }
51 if !src.is_null() {
52 mapping_matrix_multiply_channel_out_float(
53 matrix,
54 src,
55 dst_channel,
56 src_stride,
57 float_dst,
58 dst_stride,
59 frame_size,
60 );
61 }
62}
63unsafe fn opus_projection_copy_channel_out_short(
64 dst: *mut core::ffi::c_void,
65 dst_stride: i32,
66 dst_channel: i32,
67 src: *const opus_val16,
68 src_stride: i32,
69 frame_size: i32,
70 user_data: *mut core::ffi::c_void,
71) {
72 let mut short_dst: *mut i16 = 0 as *mut i16;
73 let mut matrix: *const MappingMatrix = 0 as *const MappingMatrix;
74 short_dst = dst as *mut i16;
75 matrix = user_data as *const MappingMatrix;
76 if dst_channel == 0 {
77 memset(
78 short_dst as *mut core::ffi::c_void,
79 0,
80 ((frame_size * dst_stride) as u64).wrapping_mul(::core::mem::size_of::<i16>() as u64),
81 );
82 }
83 if !src.is_null() {
84 mapping_matrix_multiply_channel_out_short(
85 matrix,
86 src,
87 dst_channel,
88 src_stride,
89 short_dst,
90 dst_stride,
91 frame_size,
92 );
93 }
94}
95unsafe fn get_dec_demixing_matrix(st: *mut OpusProjectionDecoder) -> *mut MappingMatrix {
96 return (st as *mut i8)
97 .offset(align(::core::mem::size_of::<OpusProjectionDecoder>() as u64 as i32) as isize)
98 as *mut core::ffi::c_void as *mut MappingMatrix;
99}
100unsafe fn get_multistream_decoder(st: *mut OpusProjectionDecoder) -> *mut OpusMSDecoder {
101 return (st as *mut i8).offset(align(
102 (::core::mem::size_of::<OpusProjectionDecoder>() as u64)
103 .wrapping_add((*st).demixing_matrix_size_in_bytes as u64) as i32,
104 ) as isize) as *mut core::ffi::c_void as *mut OpusMSDecoder;
105}
106pub unsafe fn opus_projection_decoder_get_size(
107 channels: i32,
108 streams: i32,
109 coupled_streams: i32,
110) -> i32 {
111 let mut matrix_size: i32 = 0;
112 let mut decoder_size: i32 = 0;
113 matrix_size = mapping_matrix_get_size(streams + coupled_streams, channels);
114 if matrix_size == 0 {
115 return 0;
116 }
117 decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams);
118 if decoder_size == 0 {
119 return 0;
120 }
121 return align(::core::mem::size_of::<OpusProjectionDecoder>() as u64 as i32)
122 + matrix_size
123 + decoder_size;
124}
125pub unsafe fn opus_projection_decoder_init(
126 st: *mut OpusProjectionDecoder,
127 Fs: i32,
128 channels: i32,
129 streams: i32,
130 coupled_streams: i32,
131 demixing_matrix: *mut u8,
132 demixing_matrix_size: i32,
133) -> i32 {
134 let mut nb_input_streams: i32 = 0;
135 let mut expected_matrix_size: i32 = 0;
136 let mut i: i32 = 0;
137 let mut ret: i32 = 0;
138 let mut mapping: [u8; 255] = [0; 255];
139 nb_input_streams = streams + coupled_streams;
140 expected_matrix_size = ((nb_input_streams * channels) as u64)
141 .wrapping_mul(::core::mem::size_of::<i16>() as u64) as i32;
142 if expected_matrix_size != demixing_matrix_size {
143 return OPUS_BAD_ARG;
144 }
145 let vla = (nb_input_streams * channels) as usize;
146 let mut buf: Vec<i16> = ::std::vec::from_elem(0, vla);
147 i = 0;
148 while i < nb_input_streams * channels {
149 let mut s: i32 = (*demixing_matrix.offset((2 * i + 1) as isize) as i32) << 8
150 | *demixing_matrix.offset((2 * i) as isize) as i32;
151 s = (s & 0xffff ^ 0x8000) - 0x8000;
152 *buf.as_mut_ptr().offset(i as isize) = s as i16;
153 i += 1;
154 }
155 (*st).demixing_matrix_size_in_bytes = mapping_matrix_get_size(channels, nb_input_streams);
156 if (*st).demixing_matrix_size_in_bytes == 0 {
157 return OPUS_BAD_ARG;
158 }
159 mapping_matrix_init(
160 get_dec_demixing_matrix(st),
161 channels,
162 nb_input_streams,
163 0,
164 buf.as_mut_ptr(),
165 demixing_matrix_size,
166 );
167 i = 0;
168 while i < channels {
169 mapping[i as usize] = i as u8;
170 i += 1;
171 }
172 ret = opus_multistream_decoder_init(
173 get_multistream_decoder(st),
174 Fs,
175 channels,
176 streams,
177 coupled_streams,
178 mapping.as_mut_ptr(),
179 );
180 return ret;
181}
182pub unsafe fn opus_projection_decoder_create(
183 Fs: i32,
184 channels: i32,
185 streams: i32,
186 coupled_streams: i32,
187 demixing_matrix: *mut u8,
188 demixing_matrix_size: i32,
189 error: *mut i32,
190) -> *mut OpusProjectionDecoder {
191 let mut size: i32 = 0;
192 let mut ret: i32 = 0;
193 let mut st: *mut OpusProjectionDecoder = 0 as *mut OpusProjectionDecoder;
194 size = opus_projection_decoder_get_size(channels, streams, coupled_streams);
195 if size == 0 {
196 if !error.is_null() {
197 *error = OPUS_ALLOC_FAIL;
198 }
199 return NULL as *mut OpusProjectionDecoder;
200 }
201 st = malloc(size as size_t) as *mut OpusProjectionDecoder;
202 if st.is_null() {
203 if !error.is_null() {
204 *error = OPUS_ALLOC_FAIL;
205 }
206 return NULL as *mut OpusProjectionDecoder;
207 }
208 ret = opus_projection_decoder_init(
209 st,
210 Fs,
211 channels,
212 streams,
213 coupled_streams,
214 demixing_matrix,
215 demixing_matrix_size,
216 );
217 if ret != OPUS_OK {
218 free(st as *mut core::ffi::c_void);
219 st = NULL as *mut OpusProjectionDecoder;
220 }
221 if !error.is_null() {
222 *error = ret;
223 }
224 return st;
225}
226pub unsafe fn opus_projection_decode(
227 st: *mut OpusProjectionDecoder,
228 data: *const u8,
229 len: i32,
230 pcm: *mut i16,
231 frame_size: i32,
232 decode_fec: i32,
233) -> i32 {
234 return opus_multistream_decode_native(
235 get_multistream_decoder(st),
236 data,
237 len,
238 pcm as *mut core::ffi::c_void,
239 Some(
240 opus_projection_copy_channel_out_short
241 as unsafe fn(
242 *mut core::ffi::c_void,
243 i32,
244 i32,
245 *const opus_val16,
246 i32,
247 i32,
248 *mut core::ffi::c_void,
249 ) -> (),
250 ),
251 frame_size,
252 decode_fec,
253 1,
254 get_dec_demixing_matrix(st) as *mut core::ffi::c_void,
255 );
256}
257pub unsafe fn opus_projection_decode_float(
258 st: *mut OpusProjectionDecoder,
259 data: *const u8,
260 len: i32,
261 pcm: *mut f32,
262 frame_size: i32,
263 decode_fec: i32,
264) -> i32 {
265 return opus_multistream_decode_native(
266 get_multistream_decoder(st),
267 data,
268 len,
269 pcm as *mut core::ffi::c_void,
270 Some(
271 opus_projection_copy_channel_out_float
272 as unsafe fn(
273 *mut core::ffi::c_void,
274 i32,
275 i32,
276 *const opus_val16,
277 i32,
278 i32,
279 *mut core::ffi::c_void,
280 ) -> (),
281 ),
282 frame_size,
283 decode_fec,
284 0,
285 get_dec_demixing_matrix(st) as *mut core::ffi::c_void,
286 );
287}
288pub unsafe fn opus_projection_decoder_ctl_impl(
289 st: *mut OpusProjectionDecoder,
290 request: i32,
291 args: VarArgs,
292) -> i32 {
293 let mut ret: i32 = OPUS_OK;
294 ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st), request, args);
295 return ret;
296}
297#[macro_export]
298macro_rules! opus_projection_decoder_ctl {
299 ($st:expr, $request:expr, $($arg:expr),*) => {
300 $crate::opus_projection_decoder_ctl_impl($st, $request, $crate::varargs!($($arg),*))
301 };
302 ($st:expr, $request:expr) => {
303 opus_projection_decoder_ctl!($st, $request,)
304 };
305 ($st:expr, $request:expr, $($arg:expr),*,) => {
306 opus_projection_decoder_ctl!($st, $request, $($arg),*)
307 };
308}
309pub unsafe fn opus_projection_decoder_destroy(st: *mut OpusProjectionDecoder) {
310 free(st as *mut core::ffi::c_void);
311}