some AudioSpec usage cleanups and minor improvements
This commit is contained in:
parent
e4a90e7f10
commit
9c35d670fa
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue