Skip to main content

soxr_ax/
lib.rs

1#![no_std]
2
3pub mod buffer;
4pub mod error;
5pub mod format;
6pub mod params;
7pub mod raw;
8
9pub use error::Error;
10
11use core::ffi::c_uint;
12use core::{marker::PhantomData, ptr::null};
13use core::ptr::null_mut;
14
15use libsoxr_ax_sys as sys;
16
17use format::IoFormat;
18use params::{QualitySpec, RuntimeSpec, QualityRecipe};
19use raw::SoxrPtr;
20
21pub type ChannelCount = usize;
22
23pub struct Soxr<Format: IoFormat> {
24    soxr: SoxrPtr,
25    _phantom: PhantomData<Format>,
26}
27
28impl<Format: IoFormat> Soxr<Format> {
29    /// Creates a new resampler instance using default values for quality
30    /// and runtime parameters
31    pub fn new(input_rate: f64, output_rate: f64) -> Result<Self, Error> {
32        Self::new_with_params(
33            input_rate,
34            output_rate,
35            QualitySpec::default(),
36            RuntimeSpec::default(),
37        )
38    }
39
40    /// Creates a new variable rate resampler instance using default values
41    /// for quality and runtime parameters
42    pub fn variable_rate(input_rate: f64, output_rate: f64)
43        -> Result<Self, Error>
44    {
45        Self::new_with_params(
46            input_rate,
47            output_rate,
48            QualitySpec::variable_rate(QualityRecipe::default()),
49            RuntimeSpec::default(),
50        )
51    }
52
53    /// Creates a new resampler instance with the specified quality and
54    /// runtime parameters
55    pub fn new_with_params(
56        input_rate: f64,
57        output_rate: f64,
58        quality: QualitySpec,
59        runtime: RuntimeSpec,
60    ) -> Result<Self, Error> {
61        let io = sys::soxr_io_spec {
62            itype: Format::datatype(),
63            otype: Format::datatype(),
64            scale: 1.0,
65            e: null_mut(),
66            flags: 0,
67        };
68
69        let channels = c_uint::try_from(Format::channels())
70            .map_err(|_| error::CHANNEL_COUNT_TOO_LARGE)?;
71
72        let soxr = unsafe {
73            let mut error = null();
74
75            let ptr = sys::soxr_create(
76                input_rate,
77                output_rate,
78                channels,
79                &mut error,
80                &io,
81                quality.as_raw(),
82                runtime.as_raw(),
83            );
84
85            if ptr == null_mut() {
86                return Err(Error::from_raw(error));
87            }
88
89            SoxrPtr::from_raw(ptr)
90        };
91
92        Ok(Soxr {
93            soxr,
94            _phantom: PhantomData,
95        })
96    }
97
98    pub fn as_ptr(&self) -> sys::soxr_t {
99        self.soxr.as_ptr()
100    }
101
102    /// Process audio through the sampler. Once finished, call `drain` until
103    /// it returns `0``.
104    pub fn process<'a>(&mut self, input: &Format::Input<'a>, output: &mut Format::Output<'a>)
105        -> Result<Processed, Error>
106    {
107        let input_len = Format::input_len(input);
108        let output_len = Format::output_len(output);
109
110        let mut input_consumed = 0;
111        let mut output_produced = 0;
112
113        unsafe {
114            let input_ptr = Format::input_ptr(input);
115            let output_ptr = Format::output_ptr(output);
116
117            Error::check(sys::soxr_process(
118                self.as_ptr(),
119                input_ptr,
120                input_len,
121                &mut input_consumed,
122                output_ptr,
123                output_len,
124                &mut output_produced,
125            ))?;
126        }
127
128        Ok(Processed {
129            input_frames: input_consumed,
130            output_frames: output_produced,
131        })
132    }
133
134    /// Indicate to the resampler that the input stream has finished, and
135    /// read remaining buffered data out of resampler
136    pub fn drain<'a>(&mut self, output: &mut Format::Output<'a>) -> Result<usize, Error> {
137        let output_len = Format::output_len(output);
138        let mut output_produced = 0;
139
140        unsafe {
141            let output_ptr = Format::output_ptr(output);
142
143            Error::check(sys::soxr_process(
144                self.as_ptr(),
145                null(),
146                0,
147                null_mut(),
148                output_ptr,
149                output_len,
150                &mut output_produced,
151            ))?;
152        }
153
154        Ok(output_produced)
155    }
156
157    pub fn clear(&mut self) -> Result<(), Error> {
158        unsafe { Error::check(sys::soxr_clear(self.as_ptr())) }
159    }
160
161    /// Change the resampler's input and output sample rates, smoothly
162    /// changing over `slew_len` frames. Set `slew_len` to 0 to change
163    /// rates immediately.
164    pub fn set_rates(&mut self, input_rate: f64, output_rate: f64, slew_len: usize)
165        -> Result<(), Error>
166    {
167        self.set_io_ratio(input_rate / output_rate, slew_len)
168    }
169
170    /// Change the resampler's input/output sample ratio, smoothly changing
171    /// over `slew_len` frames. Set `slew_len` to 0 to change rates
172    /// immediately.
173    pub fn set_io_ratio(&mut self, ratio: f64, slew_len: usize)
174        -> Result<(), Error>
175    {
176        unsafe {
177            Error::check(sys::soxr_set_io_ratio(
178                self.as_ptr(),
179                ratio,
180                slew_len,
181            ))
182        }
183    }
184}
185
186pub struct Processed {
187    pub input_frames: usize,
188    pub output_frames: usize,
189}