Maraiah/maraiah/sound.rs

100 lines
2.4 KiB
Rust
Raw Normal View History

2019-02-17 18:17:35 -08:00
//! Sound representation.
2019-06-13 18:09:07 -07:00
pub mod wav;
2019-03-01 01:27:14 -08:00
/// Any PCM stream which may be represented as a 16-bit PCM stream.
2019-02-17 18:17:35 -08:00
pub trait Sound
{
2019-03-01 01:27:14 -08:00
/// Returns the sample rate.
2019-02-17 18:17:35 -08:00
fn rate(&self) -> u16;
2019-03-01 01:27:14 -08:00
/// Returns the number of samples.
2019-02-17 18:17:35 -08:00
fn len(&self) -> usize;
2019-03-01 01:27:14 -08:00
/// Returns the `n`th sample.
///
2019-03-18 05:18:46 -07:00
/// # Panics
///
/// Panics if `n` exceeds the length of this sound.
2019-03-01 01:27:14 -08:00
fn index(&self, n: usize) -> i16;
/// Returns the number of the first sample of the loop, or `0`.
2019-02-17 19:25:20 -08:00
fn lp_beg(&self) -> usize;
2019-03-01 01:27:14 -08:00
/// Returns the number of the last sample of the loop, or `0`.
2019-02-17 19:25:20 -08:00
fn lp_end(&self) -> usize;
2019-02-17 18:17:35 -08:00
2019-03-01 01:27:14 -08:00
/// Returns `true` if there are no samples in this sound.
2019-02-20 18:33:57 -08:00
fn is_empty(&self) -> bool {self.len() == 0}
2019-02-17 18:17:35 -08:00
2019-03-01 01:27:14 -08:00
/// The same as `index`, but will not panic if out of bounds.
fn get(&self, n: usize) -> Option<i16>
2019-02-17 18:17:35 -08:00
{
2019-03-01 01:27:14 -08:00
if n < self.len() {
Some(self.index(n))
2019-02-17 18:17:35 -08:00
} else {
None
}
}
}
impl Sound16
{
2019-02-24 20:34:59 -08:00
/// Creates a new `Sound16`.
2019-02-17 19:25:20 -08:00
pub fn new(rate: u16, lp_beg: usize, lp_end: usize, len: usize) -> Self
2019-02-17 18:17:35 -08:00
{
2019-02-17 19:25:20 -08:00
Self{rate, lp_beg, lp_end, data: Vec::with_capacity(len)}
2019-02-17 18:17:35 -08:00
}
2019-02-24 20:34:59 -08:00
/// Creates a new `Sound16` from an unsigned 8-bit stream.
2019-05-30 18:29:37 -07:00
pub fn new_from_8(rate: u16, lp_beg: usize, lp_end: usize, b: &[u8]) -> Self
2019-02-17 18:17:35 -08:00
{
2019-02-24 20:34:59 -08:00
let mut snd = Self::new(rate, lp_beg, lp_end, b.len());
2019-02-17 18:17:35 -08:00
for &sample in b {
2019-02-24 20:34:59 -08:00
snd.data.push(Self::sample_from_8(sample));
2019-02-17 18:17:35 -08:00
}
snd
}
2019-02-24 20:34:59 -08:00
/// Creates a new `Sound16` from a signed 16-bit stream.
2019-05-30 18:29:37 -07:00
pub fn new_from_16(rate: u16, lp_beg: usize, lp_end: usize, b: &[u8]) -> Self
2019-02-17 18:17:35 -08:00
{
2019-02-24 20:34:59 -08:00
let mut snd = Self::new(rate, lp_beg, lp_end, b.len() / 2);
2019-02-17 18:17:35 -08:00
2019-02-17 19:25:20 -08:00
for i in (0..b.len()).step_by(2) {
snd.data.push(i16::from_le_bytes([b[i], b[i + 1]]));
2019-02-17 18:17:35 -08:00
}
snd
}
/// Creates a signed 16-bit sample from an unsigned 8-bit sample.
2019-02-20 18:33:57 -08:00
pub fn sample_from_8(sample: u8) -> i16 {(i16::from(sample) - 0x80) << 8}
2019-02-17 18:17:35 -08:00
}
impl Sound for Sound16
{
fn rate(&self) -> u16 {self.rate}
fn len(&self) -> usize {self.data.len()}
fn index(&self, p: usize) -> i16 {self.data[p]}
2019-02-17 19:25:20 -08:00
fn lp_beg(&self) -> usize {self.lp_beg}
fn lp_end(&self) -> usize {self.lp_end}
2019-02-17 18:17:35 -08:00
}
2019-03-01 01:27:14 -08:00
/// A 16-bit PCM stream.
2019-03-13 07:53:30 -07:00
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
2019-03-13 08:40:12 -07:00
#[derive(Debug, Eq, PartialEq)]
2019-02-17 18:17:35 -08:00
pub struct Sound16
{
2019-03-09 14:03:20 -08:00
rate: u16,
lp_beg: usize,
lp_end: usize,
/// The raw signed PCM data of this sound.
2019-02-17 18:17:35 -08:00
pub data: Vec<i16>,
}
// EOF