1//! SNES audio resampling code 2 3use crate::apu; 4use bincode::{Decode, Encode}; 5use dsp::design::FilterType; 6use dsp::iir::FirstOrderIirFilter; 7use dsp::sinc::QualitySincResampler; 8use jgenesis_common::frontend::AudioOutput; 9 10const SNES_AUDIO_FREQUENCY: f64 = apu::OUTPUT_FREQUENCY as f64; 11 12fn new_dc_offset_filter() -> FirstOrderIirFilter { 13 dsp::design::butterworth(5.0, SNES_AUDIO_FREQUENCY, FilterType::HighPass) 14} 15 16#[derive(Debug, Clone, Encode, Decode)] 17pub struct AudioResampler { 18 dc_offset_l: FirstOrderIirFilter, 19 dc_offset_r: FirstOrderIirFilter, 20 resampler: QualitySincResampler<2>, 21} 22 23impl AudioResampler { 24 pub fn new() -> Self { 25 Self { 26 dc_offset_l: new_dc_offset_filter(), 27 dc_offset_r: new_dc_offset_filter(), 28 resampler: QualitySincResampler::new(SNES_AUDIO_FREQUENCY, 48000.0), 29 } 30 } 31 32 pub fn collect_sample(&mut self, sample_l: f64, sample_r: f64) { 33 let sample_l = self.dc_offset_l.filter(sample_l); 34 let sample_r = self.dc_offset_r.filter(sample_r); 35 self.resampler.collect([sample_l, sample_r]); 36 } 37 38 pub fn output_samples<A: AudioOutput>(&mut self, audio_output: &mut A) -> Result<(), A::Err> { 39 while let Some([sample_l, sample_r]) = self.resampler.output_buffer_pop_front() { 40 audio_output.push_sample(sample_l, sample_r)?; 41 } 42 43 Ok(()) 44 } 45 46 pub fn update_output_frequency(&mut self, output_frequency: u64) { 47 self.resampler.update_output_frequency(output_frequency as f64); 48 } 49}