opus_embedded_sys/
lib.rs

1/*
2 * Copyright (c) 2025 Tomi Leppänen
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5/*!
6 * Minimal bindings for opus decoder.
7 *
8 * Focused on no_alloc use on embedded ARM platforms.
9 *
10 * The documentation is not very well-formatted in places and you might want to look at [Opus
11 * documentation instead](https://www.opus-codec.org/docs/html_api/index.html) instead. In
12 * particular, the page about [Opus
13 * Decoder](https://www.opus-codec.org/docs/html_api/group__opusdecoder.html) may be handy.
14 */
15
16#![allow(non_camel_case_types)]
17#![allow(non_snake_case)]
18#![no_std]
19
20#[cfg(target_os = "none")]
21use core::ffi::{c_char, c_int, CStr};
22
23pub const OPUS_DECODER_SIZE_CH1: usize = 17860;
24pub const OPUS_DECODER_SIZE_CH2: usize = 26580;
25
26include!(concat!(env!("OUT_DIR"), "/opus_decoder_gen.rs"));
27
28#[cfg(target_os = "none")]
29#[no_mangle]
30pub unsafe extern "C" fn celt_fatal(str_: *const c_char, file: *const c_char, line: c_int) {
31    /*!
32     * Celt fatal implementation that doesn't need C stdlib.
33     *
34     * # Panics
35     * Always.
36     *
37     * # Safety
38     * Caller should ensure that these are valid C strings. Additionally this checks for null
39     * pointers.
40     */
41    unsafe {
42        if str_.is_null() {
43            panic!("celt_fatal: str_ is null");
44        }
45        if file.is_null() {
46            panic!("celt_fatal: file is null");
47        }
48        let str_ = CStr::from_ptr(str_);
49        let file = CStr::from_ptr(file);
50        panic!(
51            "{}: {}: {}",
52            str_.to_str().unwrap(),
53            file.to_str().unwrap(),
54            line
55        );
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn check_reported_size() {
65        let size = unsafe { opus_decoder_get_size(1) };
66        assert_eq!(size, OPUS_DECODER_SIZE_CH1.try_into().unwrap());
67        let size = unsafe { opus_decoder_get_size(2) };
68        assert_eq!(size, OPUS_DECODER_SIZE_CH2.try_into().unwrap());
69    }
70
71    #[test]
72    fn check_struct_size() {
73        assert_eq!(
74            core::mem::size_of::<OpusDecoder>(),
75            if cfg!(feature = "stereo") {
76                OPUS_DECODER_SIZE_CH2
77            } else {
78                OPUS_DECODER_SIZE_CH1
79            }
80        );
81    }
82}