unsafe_libopus/src/
opus_projection_decoder.rs

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}