unsafe_libopus/src/
opus.rs

1pub mod stddef_h {
2    pub const NULL: i32 = 0;
3}
4pub use self::stddef_h::NULL;
5use crate::src::opus_defines::{OPUS_BAD_ARG, OPUS_INVALID_PACKET};
6
7pub unsafe fn opus_pcm_soft_clip(mut _x: *mut f32, N: i32, C: i32, declip_mem: *mut f32) {
8    let mut c: i32 = 0;
9    let mut i: i32 = 0;
10    let mut x: *mut f32 = 0 as *mut f32;
11    if C < 1 || N < 1 || _x.is_null() || declip_mem.is_null() {
12        return;
13    }
14    i = 0;
15    while i < N * C {
16        *_x.offset(i as isize) = if -2.0f32
17            > (if 2.0f32 < *_x.offset(i as isize) {
18                2.0f32
19            } else {
20                *_x.offset(i as isize)
21            }) {
22            -2.0f32
23        } else if 2.0f32 < *_x.offset(i as isize) {
24            2.0f32
25        } else {
26            *_x.offset(i as isize)
27        };
28        i += 1;
29    }
30    c = 0;
31    while c < C {
32        let mut a: f32 = 0.;
33        let mut x0: f32 = 0.;
34        let mut curr: i32 = 0;
35        x = _x.offset(c as isize);
36        a = *declip_mem.offset(c as isize);
37        i = 0;
38        while i < N {
39            if *x.offset((i * C) as isize) * a >= 0 as f32 {
40                break;
41            }
42            *x.offset((i * C) as isize) = *x.offset((i * C) as isize)
43                + a * *x.offset((i * C) as isize) * *x.offset((i * C) as isize);
44            i += 1;
45        }
46        curr = 0;
47        x0 = *x.offset(0 as isize);
48        loop {
49            let mut start: i32 = 0;
50            let mut end: i32 = 0;
51            let mut maxval: f32 = 0.;
52            let mut special: i32 = 0;
53            let mut peak_pos: i32 = 0;
54            i = curr;
55            while i < N {
56                if *x.offset((i * C) as isize) > 1 as f32 || *x.offset((i * C) as isize) < -1 as f32
57                {
58                    break;
59                }
60                i += 1;
61            }
62            if i == N {
63                a = 0 as f32;
64                break;
65            } else {
66                peak_pos = i;
67                end = i;
68                start = end;
69                maxval = (*x.offset((i * C) as isize)).abs();
70                while start > 0
71                    && *x.offset((i * C) as isize) * *x.offset(((start - 1) * C) as isize)
72                        >= 0 as f32
73                {
74                    start -= 1;
75                }
76                while end < N
77                    && *x.offset((i * C) as isize) * *x.offset((end * C) as isize) >= 0 as f32
78                {
79                    if (*x.offset((end * C) as isize)).abs() > maxval {
80                        maxval = (*x.offset((end * C) as isize)).abs();
81                        peak_pos = end;
82                    }
83                    end += 1;
84                }
85                special = (start == 0
86                    && *x.offset((i * C) as isize) * *x.offset(0 as isize) >= 0 as f32)
87                    as i32;
88                a = (maxval - 1 as f32) / (maxval * maxval);
89                a += a * 2.4e-7f32;
90                if *x.offset((i * C) as isize) > 0 as f32 {
91                    a = -a;
92                }
93                i = start;
94                while i < end {
95                    *x.offset((i * C) as isize) = *x.offset((i * C) as isize)
96                        + a * *x.offset((i * C) as isize) * *x.offset((i * C) as isize);
97                    i += 1;
98                }
99                if special != 0 && peak_pos >= 2 {
100                    let mut delta: f32 = 0.;
101                    let mut offset: f32 = x0 - *x.offset(0 as isize);
102                    delta = offset / peak_pos as f32;
103                    i = curr;
104                    while i < peak_pos {
105                        offset -= delta;
106                        *x.offset((i * C) as isize) += offset;
107                        *x.offset((i * C) as isize) = if -1.0f32
108                            > (if 1.0f32 < *x.offset((i * C) as isize) {
109                                1.0f32
110                            } else {
111                                *x.offset((i * C) as isize)
112                            }) {
113                            -1.0f32
114                        } else if 1.0f32 < *x.offset((i * C) as isize) {
115                            1.0f32
116                        } else {
117                            *x.offset((i * C) as isize)
118                        };
119                        i += 1;
120                    }
121                }
122                curr = end;
123                if curr == N {
124                    break;
125                }
126            }
127        }
128        *declip_mem.offset(c as isize) = a;
129        c += 1;
130    }
131}
132pub unsafe fn encode_size(size: i32, data: *mut u8) -> i32 {
133    if size < 252 {
134        *data.offset(0 as isize) = size as u8;
135        return 1;
136    } else {
137        *data.offset(0 as isize) = (252 + (size & 0x3)) as u8;
138        *data.offset(1 as isize) = (size - *data.offset(0 as isize) as i32 >> 2) as u8;
139        return 2;
140    };
141}
142unsafe fn parse_size(data: *const u8, len: i32, size: *mut i16) -> i32 {
143    if len < 1 {
144        *size = -1 as i16;
145        return -1;
146    } else if (*data.offset(0 as isize) as i32) < 252 {
147        *size = *data.offset(0 as isize) as i16;
148        return 1;
149    } else if len < 2 {
150        *size = -1 as i16;
151        return -1;
152    } else {
153        *size = (4 * *data.offset(1 as isize) as i32 + *data.offset(0 as isize) as i32) as i16;
154        return 2;
155    };
156}
157pub unsafe fn opus_packet_get_samples_per_frame(data: *const u8, Fs: i32) -> i32 {
158    let mut audiosize: i32 = 0;
159    if *data.offset(0 as isize) as i32 & 0x80 != 0 {
160        audiosize = *data.offset(0 as isize) as i32 >> 3 & 0x3;
161        audiosize = (Fs << audiosize) / 400;
162    } else if *data.offset(0 as isize) as i32 & 0x60 == 0x60 {
163        audiosize = if *data.offset(0 as isize) as i32 & 0x8 != 0 {
164            Fs / 50
165        } else {
166            Fs / 100
167        };
168    } else {
169        audiosize = *data.offset(0 as isize) as i32 >> 3 & 0x3;
170        if audiosize == 3 {
171            audiosize = Fs * 60 / 1000;
172        } else {
173            audiosize = (Fs << audiosize) / 100;
174        }
175    }
176    return audiosize;
177}
178pub unsafe fn opus_packet_parse_impl(
179    mut data: *const u8,
180    mut len: i32,
181    self_delimited: i32,
182    out_toc: *mut u8,
183    frames: *mut *const u8,
184    size: *mut i16,
185    payload_offset: *mut i32,
186    packet_offset: *mut i32,
187) -> i32 {
188    let mut i: i32 = 0;
189    let mut bytes: i32 = 0;
190    let mut count: i32 = 0;
191    let mut cbr: i32 = 0;
192    let mut ch: u8 = 0;
193    let mut toc: u8 = 0;
194    let mut framesize: i32 = 0;
195    let mut last_size: i32 = 0;
196    let mut pad: i32 = 0;
197    let data0: *const u8 = data;
198    if size.is_null() || len < 0 {
199        return OPUS_BAD_ARG;
200    }
201    if len == 0 {
202        return OPUS_INVALID_PACKET;
203    }
204    framesize = opus_packet_get_samples_per_frame(data, 48000);
205    cbr = 0;
206    let fresh0 = data;
207    data = data.offset(1);
208    toc = *fresh0;
209    len -= 1;
210    last_size = len;
211    match toc as i32 & 0x3 {
212        0 => {
213            count = 1;
214        }
215        1 => {
216            count = 2;
217            cbr = 1;
218            if self_delimited == 0 {
219                if len & 0x1 != 0 {
220                    return OPUS_INVALID_PACKET;
221                }
222                last_size = len / 2;
223                *size.offset(0 as isize) = last_size as i16;
224            }
225        }
226        2 => {
227            count = 2;
228            bytes = parse_size(data, len, size);
229            len -= bytes;
230            if (*size.offset(0 as isize) as i32) < 0 || *size.offset(0 as isize) as i32 > len {
231                return OPUS_INVALID_PACKET;
232            }
233            data = data.offset(bytes as isize);
234            last_size = len - *size.offset(0 as isize) as i32;
235        }
236        _ => {
237            if len < 1 {
238                return OPUS_INVALID_PACKET;
239            }
240            let fresh1 = data;
241            data = data.offset(1);
242            ch = *fresh1;
243            count = ch as i32 & 0x3f;
244            if count <= 0 || framesize * count > 5760 {
245                return OPUS_INVALID_PACKET;
246            }
247            len -= 1;
248            if ch as i32 & 0x40 != 0 {
249                let mut p: i32 = 0;
250                loop {
251                    let mut tmp: i32 = 0;
252                    if len <= 0 {
253                        return OPUS_INVALID_PACKET;
254                    }
255                    let fresh2 = data;
256                    data = data.offset(1);
257                    p = *fresh2 as i32;
258                    len -= 1;
259                    tmp = if p == 255 { 254 } else { p };
260                    len -= tmp;
261                    pad += tmp;
262                    if !(p == 255) {
263                        break;
264                    }
265                }
266            }
267            if len < 0 {
268                return OPUS_INVALID_PACKET;
269            }
270            cbr = (ch as i32 & 0x80 == 0) as i32;
271            if cbr == 0 {
272                last_size = len;
273                i = 0;
274                while i < count - 1 {
275                    bytes = parse_size(data, len, size.offset(i as isize));
276                    len -= bytes;
277                    if (*size.offset(i as isize) as i32) < 0
278                        || *size.offset(i as isize) as i32 > len
279                    {
280                        return OPUS_INVALID_PACKET;
281                    }
282                    data = data.offset(bytes as isize);
283                    last_size -= bytes + *size.offset(i as isize) as i32;
284                    i += 1;
285                }
286                if last_size < 0 {
287                    return OPUS_INVALID_PACKET;
288                }
289            } else if self_delimited == 0 {
290                last_size = len / count;
291                if last_size * count != len {
292                    return OPUS_INVALID_PACKET;
293                }
294                i = 0;
295                while i < count - 1 {
296                    *size.offset(i as isize) = last_size as i16;
297                    i += 1;
298                }
299            }
300        }
301    }
302    if self_delimited != 0 {
303        bytes = parse_size(data, len, size.offset(count as isize).offset(-(1 as isize)));
304        len -= bytes;
305        if (*size.offset((count - 1) as isize) as i32) < 0
306            || *size.offset((count - 1) as isize) as i32 > len
307        {
308            return OPUS_INVALID_PACKET;
309        }
310        data = data.offset(bytes as isize);
311        if cbr != 0 {
312            if *size.offset((count - 1) as isize) as i32 * count > len {
313                return OPUS_INVALID_PACKET;
314            }
315            i = 0;
316            while i < count - 1 {
317                *size.offset(i as isize) = *size.offset((count - 1) as isize);
318                i += 1;
319            }
320        } else if bytes + *size.offset((count - 1) as isize) as i32 > last_size {
321            return OPUS_INVALID_PACKET;
322        }
323    } else {
324        if last_size > 1275 {
325            return OPUS_INVALID_PACKET;
326        }
327        *size.offset((count - 1) as isize) = last_size as i16;
328    }
329    if !payload_offset.is_null() {
330        *payload_offset = data.offset_from(data0) as i64 as i32;
331    }
332    i = 0;
333    while i < count {
334        if !frames.is_null() {
335            let ref mut fresh3 = *frames.offset(i as isize);
336            *fresh3 = data;
337        }
338        data = data.offset(*size.offset(i as isize) as i32 as isize);
339        i += 1;
340    }
341    if !packet_offset.is_null() {
342        *packet_offset = pad + data.offset_from(data0) as i64 as i32;
343    }
344    if !out_toc.is_null() {
345        *out_toc = toc;
346    }
347    return count;
348}
349pub unsafe fn opus_packet_parse(
350    data: *const u8,
351    len: i32,
352    out_toc: *mut u8,
353    frames: *mut *const u8,
354    size: *mut i16,
355    payload_offset: *mut i32,
356) -> i32 {
357    return opus_packet_parse_impl(
358        data,
359        len,
360        0,
361        out_toc,
362        frames,
363        size,
364        payload_offset,
365        NULL as *mut i32,
366    );
367}