some AudioSpec usage cleanups and minor improvements

This commit is contained in:
Gered 2022-05-29 11:19:57 -04:00
parent e4a90e7f10
commit 9c35d670fa
3 changed files with 37 additions and 27 deletions

View file

@ -1,6 +1,6 @@
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use sdl2::audio::AudioCallback; use sdl2::audio::{AudioCallback, AudioFormat};
use thiserror::Error; use thiserror::Error;
pub use self::wav::*; pub use self::wav::*;
@ -15,13 +15,24 @@ pub const AUDIO_FREQUENCY_11KHZ: u32 = 11025;
pub const SILENCE: u8 = sdl2::audio::AudioFormatNum::SILENCE; pub const SILENCE: u8 = sdl2::audio::AudioFormatNum::SILENCE;
pub const TARGET_AUDIO_SPEC: AudioSpec = AudioSpec { frequency: AUDIO_FREQUENCY_22KHZ, channels: 1, format: AudioFormat::U8 };
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct AudioSpec { pub struct AudioSpec {
pub frequency: u32, frequency: u32,
pub channels: u8, channels: u8,
format: AudioFormat,
} }
impl AudioSpec { impl AudioSpec {
pub fn new(frequency: u32, channels: u8, format: AudioFormat) -> Self {
AudioSpec {
frequency,
channels,
format
}
}
#[inline] #[inline]
pub fn frequency(&self) -> u32 { pub fn frequency(&self) -> u32 {
self.frequency self.frequency
@ -31,6 +42,11 @@ impl AudioSpec {
pub fn channels(&self) -> u8 { pub fn channels(&self) -> u8 {
self.channels self.channels
} }
#[inline]
pub fn format(&self) -> AudioFormat {
self.format
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -264,12 +280,9 @@ pub struct AudioBuffer {
} }
impl AudioBuffer { impl AudioBuffer {
pub fn new(frequency: u32, channels: u8) -> Self { pub fn new(spec: AudioSpec) -> Self {
AudioBuffer { AudioBuffer {
spec: AudioSpec { spec,
frequency,
channels,
},
data: Vec::new(), data: Vec::new(),
} }
} }
@ -279,22 +292,21 @@ impl AudioBuffer {
&self.spec &self.spec
} }
pub fn convert(self, frequency: u32, channels: u8) -> Result<Self, AudioBufferError> { pub fn convert(self, to_spec: &AudioSpec) -> Result<Self, AudioBufferError> {
if self.spec.frequency == frequency && self.spec.channels == channels { if self.spec == *to_spec {
Ok(self) Ok(self)
} else { } else {
use sdl2::audio::AudioFormat;
let converter = sdl2::audio::AudioCVT::new( let converter = sdl2::audio::AudioCVT::new(
AudioFormat::U8, self.spec.format(),
self.spec.channels, self.spec.channels(),
self.spec.frequency as i32, self.spec.frequency() as i32,
AudioFormat::U8, to_spec.format(),
channels, to_spec.channels(),
frequency as i32, to_spec.frequency() as i32,
); );
match converter { match converter {
Ok(converter) => { Ok(converter) => {
let mut result = AudioBuffer::new(frequency, channels); let mut result = AudioBuffer::new(*to_spec);
result.data = converter.convert(self.data); result.data = converter.convert(self.data);
Ok(result) Ok(result)
} }

View file

@ -4,9 +4,10 @@ use std::io::{BufReader, Read, Seek, SeekFrom, Write};
use std::path::Path; use std::path::Path;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use sdl2::audio::AudioFormat;
use thiserror::Error; use thiserror::Error;
use crate::audio::AudioBuffer; use crate::audio::{AudioBuffer, AudioSpec};
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum WavError { pub enum WavError {
@ -234,7 +235,8 @@ impl AudioBuffer {
let mut audio_buffer; let mut audio_buffer;
if let Some(format) = format { if let Some(format) = format {
audio_buffer = AudioBuffer::new(format.frequency, format.channels as u8); let spec = AudioSpec::new(format.frequency, format.channels as u8, AudioFormat::U8);
audio_buffer = AudioBuffer::new(spec);
} else { } else {
return Err(WavError::BadFile(String::from("No 'fmt ' chunk was found"))); return Err(WavError::BadFile(String::from("No 'fmt ' chunk was found")));
} }

View file

@ -243,17 +243,13 @@ impl SystemBuilder {
}; };
let audio_spec = AudioSpecDesired { let audio_spec = AudioSpecDesired {
freq: Some(AUDIO_FREQUENCY_22KHZ as i32), freq: Some(TARGET_AUDIO_SPEC.frequency() as i32),
channels: Some(1), channels: Some(TARGET_AUDIO_SPEC.channels()),
samples: None, samples: None,
}; };
let audio = match sdl_audio_subsystem.open_playback(None, &audio_spec, |spec| { let audio = match sdl_audio_subsystem.open_playback(None, &audio_spec, |spec| {
let our_spec = AudioSpec { let our_spec = AudioSpec::new(spec.freq as u32, spec.channels, spec.format);
frequency: spec.freq as u32,
channels: spec.channels,
};
AudioDevice::new(our_spec) AudioDevice::new(our_spec)
}) { }) {
Ok(audio_device) => audio_device, Ok(audio_device) => audio_device,