fix audio in gpSP (sample rate too high after fixed-point conversion)

This commit is contained in:
lifning 2021-12-09 23:40:38 -08:00
parent d74f625c62
commit 904b7c2a41
1 changed files with 17 additions and 11 deletions

View File

@ -69,7 +69,8 @@ impl RetroComponent for SimpleSdl2AudioComponent {
} }
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow { fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
if let Ok(converter) = Self::make_converter(self.src_freq, self.queue.spec()) { match Self::make_converter(self.src_freq, self.queue.spec()) {
Ok(converter) => {
if !self.audio_buffer.is_empty() { if !self.audio_buffer.is_empty() {
let mut samples = std::mem::take(&mut self.audio_buffer); let mut samples = std::mem::take(&mut self.audio_buffer);
samples = resample(&converter, samples); samples = resample(&converter, samples);
@ -77,9 +78,14 @@ impl RetroComponent for SimpleSdl2AudioComponent {
self.queue.queue(&self.audio_buffer); self.queue.queue(&self.audio_buffer);
self.audio_buffer.clear(); self.audio_buffer.clear();
} }
}
ControlFlow::Continue ControlFlow::Continue
} }
Err(e) => {
eprintln!("Audio sample rate conversion failed: {:?}", e);
ControlFlow::Break
}
}
}
} }
impl SimpleSdl2AudioComponent { impl SimpleSdl2AudioComponent {
@ -105,16 +111,16 @@ impl SimpleSdl2AudioComponent {
} }
fn make_converter(src_freq: f64, dest_spec: &AudioSpec) -> Result<AudioCVT, String> { fn make_converter(src_freq: f64, dest_spec: &AudioSpec) -> Result<AudioCVT, String> {
// note on the `* 64`: as long as the ratio between src_rate and dst_rate is right, // note on the `* 16`: as long as the ratio between src_rate and dst_rate is right,
// we should be in the clear -- this is to make up for SDL not giving us floats for // we should be in the clear -- this is to make up for SDL not giving us floats for
// this, we can at least get some quasi-fixed-point precision going on... // this, we can at least get some quasi-fixed-point precision going on...
AudioCVT::new( AudioCVT::new(
AudioFormat::s16_sys(), AudioFormat::s16_sys(),
2, 2,
(src_freq * 64.0).round() as i32, (src_freq * 16.0).round() as i32,
dest_spec.format, dest_spec.format,
dest_spec.channels, dest_spec.channels,
dest_spec.freq * 64, dest_spec.freq * 16,
) )
} }
} }