1use anyhow::Result;
2
3#[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}