pub struct AudioChunk {
pts_us: Option<i64>,
index: u64,
sample_rate: u32,
channels: u16,
channel_layout: String,
data: Vec<f32>,
}
impl AudioChunk {
pub(crate) fn new(
pts_us: Option<i64>,
index: u64,
sample_rate: u32,
channels: u16,
channel_layout: String,
data: Vec<f32>,
) -> Self {
#[allow(clippy::manual_is_multiple_of)]
{
debug_assert!(
channels != 0 && data.len() % channels as usize == 0,
"AudioChunk buffer must hold whole interleaved frames"
);
}
Self {
pts_us,
index,
sample_rate,
channels,
channel_layout,
data,
}
}
pub fn pts_us(&self) -> Option<i64> {
self.pts_us
}
pub fn index(&self) -> u64 {
self.index
}
pub fn sample_rate(&self) -> u32 {
self.sample_rate
}
pub fn channels(&self) -> u16 {
self.channels
}
pub fn channel_layout(&self) -> &str {
&self.channel_layout
}
pub fn as_slice(&self) -> &[f32] {
&self.data
}
pub fn into_vec(self) -> Vec<f32> {
self.data
}
}
impl std::fmt::Debug for AudioChunk {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AudioChunk")
.field("pts_us", &self.pts_us)
.field("index", &self.index)
.field("sample_rate", &self.sample_rate)
.field("channels", &self.channels)
.field("channel_layout", &self.channel_layout)
.field("samples", &self.data.len())
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn metadata_accessors_round_trip() {
let c = AudioChunk::new(Some(40_000), 2, 48_000, 6, "5.1".to_string(), vec![0.0; 12]);
assert_eq!(c.pts_us(), Some(40_000));
assert_eq!(c.index(), 2);
assert_eq!(c.sample_rate(), 48_000);
assert_eq!(c.channels(), 6);
assert_eq!(c.channel_layout(), "5.1");
assert_eq!(c.as_slice().len(), 12);
assert_eq!(c.into_vec().len(), 12);
}
}