1mod constants; 2 3use crate::psg::PSG_FREQUENCY; 4use bincode::{Decode, Encode}; 5use dsp::sinc::PerformanceSincResampler; 6use jgenesis_common::audio::fir_resampler::{FirKernel, LpfCoefficients, StereoFirResampler}; 7use pce_config::PceAudioResampler; 8 9#[derive(Debug, Clone, Encode, Decode)] 10pub struct PsgLpfKernel; 11 12impl FirKernel<{ constants::LPF_TAPS }> for PsgLpfKernel { 13 fn lpf_coefficients() -> &'static LpfCoefficients<{ constants::LPF_TAPS }> { 14 constants::LPF_COEFFICIENTS 15 } 16} 17 18#[derive(Debug, Clone, Encode, Decode)] 19pub enum PsgResampler { 20 LowPassNearestNeighbor(StereoFirResampler<{ constants::LPF_TAPS }, PsgLpfKernel>), 21 WindowedSinc(PerformanceSincResampler<2>), 22} 23 24impl PsgResampler { 25 pub fn new(resampler: PceAudioResampler, output_frequency: u64) -> Self { 26 match resampler { 27 PceAudioResampler::WindowedSinc => Self::WindowedSinc(PerformanceSincResampler::new( 28 PSG_FREQUENCY, 29 output_frequency as f64, 30 )), 31 PceAudioResampler::LowPassNearestNeighbor => Self::LowPassNearestNeighbor( 32 StereoFirResampler::new(PSG_FREQUENCY, output_frequency), 33 ), 34 } 35 } 36 37 pub fn collect(&mut self, sample: [f64; 2]) { 38 match self { 39 Self::LowPassNearestNeighbor(resampler) => resampler.collect(sample), 40 Self::WindowedSinc(resampler) => resampler.collect(sample), 41 } 42 } 43 44 pub fn output_buffer_pop_front(&mut self) -> Option<[f64; 2]> { 45 match self { 46 Self::LowPassNearestNeighbor(resampler) => resampler.output_buffer_pop_front(), 47 Self::WindowedSinc(resampler) => resampler.output_buffer_pop_front(), 48 } 49 } 50 51 pub fn update_output_frequency(&mut self, output_frequency: f64) { 52 match self { 53 Self::LowPassNearestNeighbor(resampler) => { 54 resampler.update_output_frequency(output_frequency); 55 } 56 Self::WindowedSinc(resampler) => resampler.update_output_frequency(output_frequency), 57 } 58 } 59 60 pub fn resampler_impl(&self) -> PceAudioResampler { 61 match self { 62 Self::LowPassNearestNeighbor(..) => PceAudioResampler::LowPassNearestNeighbor, 63 Self::WindowedSinc(..) => PceAudioResampler::WindowedSinc, 64 } 65 } 66}