Skip to main content

ogg_table/
vorbis.rs

1use anyhow::Result;
2
3// https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-630004.2.2
4#[derive(Debug, Clone)]
5pub struct IdentificationHeader {
6    pub audio_channels: u8,
7    pub audio_sample_rate: u32,
8    pub bitrate_maximum: u32,
9    pub bitrate_nominal: u32,
10    pub bitrate_minimum: u32,
11    pub blocksizes: u8,
12}
13
14impl IdentificationHeader {
15    pub fn from_reader<R: std::io::Read>(rdr: &mut R) -> Result<Self> {
16        use byteorder::{LittleEndian, ReadBytesExt};
17        let packet_type = rdr.read_u8()?;
18        if packet_type != 1 {
19            anyhow::bail!("unexpected packet type for the vorbis ident header {packet_type}");
20        }
21        let mut magic = [0u8; 6];
22        rdr.read_exact(&mut magic)?;
23        if magic != *b"vorbis" {
24            anyhow::bail!("unexpected vorbis magic in header {magic:?}")
25        }
26        let vorbis_version = rdr.read_u32::<LittleEndian>()?;
27        if vorbis_version != 0 {
28            anyhow::bail!("unexpected vorbis version {vorbis_version}")
29        }
30        let audio_channels = rdr.read_u8()?;
31        let audio_sample_rate = rdr.read_u32::<LittleEndian>()?;
32        let bitrate_maximum = rdr.read_u32::<LittleEndian>()?;
33        let bitrate_nominal = rdr.read_u32::<LittleEndian>()?;
34        let bitrate_minimum = rdr.read_u32::<LittleEndian>()?;
35        let blocksizes = rdr.read_u8()?;
36        Ok(Self {
37            audio_channels,
38            audio_sample_rate,
39            bitrate_maximum,
40            bitrate_nominal,
41            bitrate_minimum,
42            blocksizes,
43        })
44    }
45}