1 use crate::formats::{NAChannelMap, NAChannelType};
2 use crate::frame::{NAAudioInfo, NABufferType};
5 #[derive(Clone,Copy,Default)]
12 fn new() -> Self { Self::default() }
13 fn add(&mut self, frac: Fraction) {
14 self.frac += frac.num;
15 while self.frac >= frac.den {
16 self.frac -= frac.den;
22 #[derive(Clone,Copy,PartialEq)]
29 fn new(a: usize, b: usize) -> Self {
30 let cur_gcd = Self::gcd(a, b);
36 fn gcd(mut a: usize, mut b: usize) -> usize {
37 while a != 0 && b != 0 {
48 fn bessel_i0(mut x: f64) -> f64 {
63 fn sinc(self) -> Self;
67 fn sinc(self) -> Self { self.sin() / self }
70 const BESSEL_BETA: f64 = 8.0;
71 fn gen_sinc_coeffs(order: usize, num: usize, den: usize, norm: f32) -> Vec<f32> {
72 let mut coeffs = vec![0.0; order * 2];
74 let sinc_scale = std::f32::consts::PI * norm / (den as f32);
75 let win_scale = 1.0 / ((order * den) as f32);
76 for (i, coef) in coeffs.iter_mut().enumerate() {
77 let pos = (((i as i32) - (order as i32)) * (den as i32) + (num as i32)) as f32;
82 let wval = f64::from((pos * win_scale).min(-1.0).max(1.0));
83 let win = bessel_i0(BESSEL_BETA - (1.0 - wval * wval).sqrt()) as f32;
84 *coef = norm * (pos * sinc_scale).sinc() * win;
88 let sum = coeffs.iter().fold(0.0f32, |acc, &x| acc + x) * norm;
89 for el in coeffs.iter_mut() {
96 /// Context for continuous audio resampling and format conversion.
97 pub struct NAResample {
98 coeffs: Vec<Vec<f32>>,
103 hist_i: Vec<Vec<i32>>,
104 hist_f: Vec<Vec<f32>>,
107 dst_info: NAAudioInfo,
108 dst_chmap: NAChannelMap,
113 pub fn new(src_rate: u32, dst_info: &NAAudioInfo, dst_chmap: &NAChannelMap, order: usize) -> Self {
114 let ratio = Fraction::new(src_rate as usize, dst_info.sample_rate as usize);
115 let nchannels = usize::from(dst_info.channels);
116 let mut coeffs = Vec::with_capacity(ratio.den);
117 let norm = if ratio.num < ratio.den { 1.0 } else { (ratio.den as f32) / (ratio.num as f32) };
118 for i in 0..ratio.den {
119 coeffs.push(gen_sinc_coeffs(order, i, ratio.den, norm));
122 let mut hist_i = Vec::with_capacity(nchannels);
123 let mut hist_f = Vec::with_capacity(nchannels);
124 if !dst_info.format.is_float() {
125 for _ in 0..(order * 2) {
126 hist_i.push(vec![0; nchannels]);
129 for _ in 0..(order * 2) {
130 hist_f.push(vec![0.0; nchannels]);
135 order, coeffs, ratio,
141 dst_chmap: dst_chmap.clone(),
145 fn reinit(&mut self, src_rate: u32) {
146 self.src_rate = src_rate;
147 self.ratio = Fraction::new(src_rate as usize, self.dst_info.sample_rate as usize);
149 let norm = if self.ratio.num < self.ratio.den { 1.0 } else { (self.ratio.den as f32) / (self.ratio.num as f32) };
150 for i in 0..self.ratio.den {
151 self.coeffs.push(gen_sinc_coeffs(self.order, i, self.ratio.den, norm));
153 self.pos = FracPos::new();
155 fn estimate_output(&self, nsamples: usize) -> usize {
156 ((nsamples + 1) * self.ratio.den - self.pos.frac) / self.ratio.num + 16
158 fn add_samples_i32(&mut self, samples: &[i32]) -> bool {
159 if self.deficit == 0 {
163 self.hist_i[self.deficit].copy_from_slice(samples);
166 fn get_samples_i32(&mut self, samples: &mut [i32]) -> bool {
167 if self.deficit != 0 {
170 let ret = self.pos.ipos == 0;
171 if self.pos.ipos == 0 {
172 for (i, dst) in samples.iter_mut().enumerate() {
174 for (hist, &coef) in self.hist_i.iter().zip(self.coeffs[self.pos.frac].iter()) {
175 sum += (hist[i] as f32) * coef;
179 self.pos.add(self.ratio);
181 if self.pos.ipos > 0 {
182 self.deficit = self.pos.ipos.min(self.hist_i.len());
183 for i in (0..(self.hist_i.len() - self.deficit)).rev() {
184 self.hist_i.swap(i, i + self.deficit)
186 self.pos.ipos -= self.deficit;
190 fn add_samples_f32(&mut self, samples: &[f32]) -> bool {
191 if self.deficit == 0 {
195 self.hist_f[self.deficit].copy_from_slice(samples);
198 fn get_samples_f32(&mut self, samples: &mut [f32]) -> bool {
199 if self.deficit != 0 {
202 let ret = self.pos.ipos == 0;
203 if self.pos.ipos == 0 {
204 for (i, dst) in samples.iter_mut().enumerate() {
206 for (hist, &coef) in self.hist_f.iter().zip(self.coeffs[self.pos.frac].iter()) {
207 sum += hist[i]* coef;
211 self.pos.add(self.ratio);
213 if self.pos.ipos > 0 {
214 self.deficit = self.pos.ipos.min(self.hist_f.len());
215 for i in (0..(self.hist_f.len() - self.deficit)).rev() {
216 self.hist_f.swap(i, i + self.deficit)
218 self.pos.ipos -= self.deficit;
222 pub fn convert_audio_frame(&mut self, src: &NABufferType) -> Result<NABufferType, SoundConvertError> {
223 let nsamples = src.get_audio_length();
225 return Err(SoundConvertError::InvalidInput);
227 let src_chmap = src.get_chmap().unwrap();
228 let src_info = src.get_audio_info().unwrap();
229 if (src_chmap.num_channels() == 0) || (self.dst_chmap.num_channels() == 0) {
230 return Err(SoundConvertError::InvalidInput);
233 let needs_remix = src_chmap.num_channels() != self.dst_chmap.num_channels();
234 let no_channel_needs = !needs_remix && channel_maps_equal(src_chmap, &self.dst_chmap);
235 let needs_reorder = !needs_remix && !no_channel_needs && channel_maps_reordered(src_chmap, &self.dst_chmap);
237 if src_info.sample_rate != self.src_rate {
238 self.reinit(src_info.sample_rate);
240 let needs_resample = src_info.sample_rate != self.dst_info.sample_rate;
242 let channel_op = if no_channel_needs {
243 ChannelOp::Passthrough
244 } else if needs_reorder {
245 let reorder_mat = calculate_reorder_matrix(src_chmap, &self.dst_chmap);
246 ChannelOp::Reorder(reorder_mat)
247 } else if src_chmap.num_channels() > 1 {
248 let remix_mat = calculate_remix_matrix(src_chmap, &self.dst_chmap);
249 ChannelOp::Remix(remix_mat)
251 let mut dup_mat: Vec<bool> = Vec::with_capacity(self.dst_chmap.num_channels());
252 for i in 0..self.dst_chmap.num_channels() {
253 let ch = self.dst_chmap.get_channel(i);
254 if ch.is_left() || ch.is_right() || ch == NAChannelType::C {
260 ChannelOp::DupMono(dup_mat)
263 let src_fmt = src_info.get_format();
264 let dst_fmt = self.dst_info.get_format();
265 let no_conversion = src_fmt == dst_fmt;
267 if no_conversion && no_channel_needs {
268 return Ok(src.clone());
271 let dst_nsamples = if !needs_resample {
274 self.estimate_output(nsamples)
276 let ret = alloc_audio_buffer(self.dst_info, dst_nsamples, self.dst_chmap.clone());
278 return Err(SoundConvertError::AllocError);
280 let mut dst_buf = ret.unwrap();
282 let sstep = src.get_audio_step().max(1);
283 let dstep = dst_buf.get_audio_step().max(1);
284 let sr: Box<dyn SampleReader> = match src {
285 NABufferType::AudioU8(ref ab) => {
286 let stride = ab.get_stride();
287 let data = ab.get_data();
289 Box::new(GenericSampleReader { data, stride })
291 Box::new(S8SampleReader { data, stride })
294 NABufferType::AudioI16(ref ab) => {
295 let data = ab.get_data();
296 let stride = ab.get_stride();
297 Box::new(GenericSampleReader { data, stride })
299 NABufferType::AudioI32(ref ab) => {
300 let data = ab.get_data();
301 let stride = ab.get_stride();
302 Box::new(GenericSampleReader { data, stride })
304 NABufferType::AudioF32(ref ab) => {
305 let data = ab.get_data();
306 let stride = ab.get_stride();
307 Box::new(GenericSampleReader { data, stride })
309 NABufferType::AudioPacked(ref ab) => {
310 let data = ab.get_data();
311 Box::new(PackedSampleReader::new(data, src_fmt))
313 _ => unimplemented!(),
315 let mut sw: Box<dyn SampleWriter> = match dst_buf {
316 NABufferType::AudioU8(ref mut ab) => {
317 let stride = ab.get_stride();
318 let data = ab.get_data_mut().unwrap();
319 Box::new(GenericSampleWriter { data, stride })
321 NABufferType::AudioI16(ref mut ab) => {
322 let stride = ab.get_stride();
323 let data = ab.get_data_mut().unwrap();
324 Box::new(GenericSampleWriter { data, stride })
326 NABufferType::AudioI32(ref mut ab) => {
327 let stride = ab.get_stride();
328 let data = ab.get_data_mut().unwrap();
329 Box::new(GenericSampleWriter { data, stride })
331 NABufferType::AudioF32(ref mut ab) => {
332 let stride = ab.get_stride();
333 let data = ab.get_data_mut().unwrap();
334 Box::new(GenericSampleWriter { data, stride })
336 NABufferType::AudioPacked(ref mut ab) => {
337 let data = ab.get_data_mut().unwrap();
338 Box::new(PackedSampleWriter::new(data, dst_fmt))
340 _ => unimplemented!(),
343 let into_float = dst_fmt.float;
346 let mut svec = vec![0; src_chmap.num_channels()];
347 let mut dvec = vec![0; self.dst_chmap.num_channels()];
348 let mut tvec = vec![0; self.dst_chmap.num_channels()];
351 for _ in 0..nsamples {
352 sr.get_samples_i32(spos, &mut svec);
353 if !channel_op.is_remix() {
354 apply_channel_op(&channel_op, &svec, &mut dvec);
356 remix_i32(&channel_op, &svec, &mut dvec);
359 sw.store_samples_i32(dpos, &dvec);
362 while self.get_samples_i32(&mut tvec) {
363 sw.store_samples_i32(dpos, &tvec);
366 self.add_samples_i32(&dvec);
371 while self.get_samples_i32(&mut tvec) {
372 sw.store_samples_i32(dpos, &tvec);
375 new_len = dpos / dstep;
378 let mut svec = vec![0.0; src_chmap.num_channels()];
379 let mut dvec = vec![0.0; self.dst_chmap.num_channels()];
380 let mut tvec = vec![0.0; self.dst_chmap.num_channels()];
383 for _ in 0..nsamples {
384 sr.get_samples_f32(spos, &mut svec);
385 if !channel_op.is_remix() {
386 apply_channel_op(&channel_op, &svec, &mut dvec);
388 remix_f32(&channel_op, &svec, &mut dvec);
391 sw.store_samples_f32(dpos, &dvec);
394 while self.get_samples_f32(&mut tvec) {
395 sw.store_samples_f32(dpos, &tvec);
398 self.add_samples_f32(&dvec);
403 while self.get_samples_f32(&mut tvec) {
404 sw.store_samples_f32(dpos, &tvec);
407 new_len = dpos / dstep;
413 dst_buf.truncate_audio(new_len);