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 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 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 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 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 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 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 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}