flac_metadata_read/
flac-metadata-read.rs1extern crate bitstream_io;
7
8use bitstream_io::{BigEndian, BitRead, BitReader, FromBitStream};
9use std::num::NonZero;
10
11#[derive(Debug, PartialEq, Eq)]
12struct BlockHeader {
13 last_block: bool, block_type: u8, block_size: u32, }
17
18impl FromBitStream for BlockHeader {
19 type Error = std::io::Error;
20
21 fn from_reader<R: BitRead + ?Sized>(r: &mut R) -> std::io::Result<Self> {
22 Ok(Self {
23 last_block: r.read_bit()?,
24 block_type: r.read::<7, _>()?,
25 block_size: r.read::<24, _>()?,
26 })
27 }
28}
29
30#[derive(Debug, PartialEq, Eq)]
31struct Streaminfo {
32 minimum_block_size: u16, maximum_block_size: u16, minimum_frame_size: u32, maximum_frame_size: u32, sample_rate: u32, channels: NonZero<u8>, bits_per_sample: NonZero<u8>, total_samples: u64, md5: [u8; 16], }
42
43impl FromBitStream for Streaminfo {
44 type Error = std::io::Error;
45
46 fn from_reader<R: BitRead + ?Sized>(r: &mut R) -> std::io::Result<Self> {
47 Ok(Self {
48 minimum_block_size: r.read_to()?,
49 maximum_block_size: r.read_to()?,
50 minimum_frame_size: r.read::<24, _>()?,
51 maximum_frame_size: r.read::<24, _>()?,
52 sample_rate: r.read::<20, _>()?,
53 channels: r.read::<3, _>()?,
54 bits_per_sample: r.read::<5, _>()?,
55 total_samples: r.read::<36, _>()?,
56 md5: r.read_to()?,
57 })
58 }
59}
60
61#[derive(Debug, PartialEq, Eq)]
62struct VorbisComment {
63 vendor: String,
64 comment: Vec<String>,
65}
66
67impl FromBitStream for VorbisComment {
68 type Error = Box<dyn std::error::Error>;
69
70 fn from_reader<R: BitRead + ?Sized>(r: &mut R) -> Result<Self, Self::Error> {
71 use bitstream_io::LE;
72
73 fn read_entry<R: BitRead + ?Sized>(
74 r: &mut R,
75 ) -> Result<String, Box<dyn std::error::Error>> {
76 use std::convert::TryInto;
77 let size = r.read_as_to::<LE, u32>()?.try_into()?;
78 Ok(String::from_utf8(r.read_to_vec(size)?)?)
79 }
80
81 Ok(Self {
82 vendor: read_entry(r)?,
83 comment: (0..r.read_as_to::<LE, u32>()?)
84 .map(|_| read_entry(r))
85 .collect::<Result<Vec<_>, _>>()?,
86 })
87 }
88}
89
90fn main() {
91 let flac = include_bytes!("data/metadata-only.flac");
93
94 let mut reader = BitReader::endian(flac.as_slice(), BigEndian);
95
96 assert_eq!(&reader.read_to::<[u8; 4]>().unwrap(), b"fLaC");
98
99 assert_eq!(
101 reader.parse::<BlockHeader>().unwrap(),
102 BlockHeader {
103 last_block: false,
104 block_type: 0,
105 block_size: 34
106 }
107 );
108
109 assert_eq!(
111 dbg!(reader.parse::<Streaminfo>().unwrap()),
112 Streaminfo {
113 minimum_block_size: 4096,
114 maximum_block_size: 4096,
115 minimum_frame_size: 1542,
116 maximum_frame_size: 8546,
117 sample_rate: 44100,
118 channels: NonZero::new(2).unwrap(),
119 bits_per_sample: NonZero::new(16).unwrap(),
120 total_samples: 304844,
121 md5: *b"\xFA\xF2\x69\x2F\xFD\xEC\x2D\x5B\x30\x01\x76\xB4\x62\x88\x7D\x92",
122 }
123 );
124
125 assert_eq!(
127 dbg!(reader.parse::<BlockHeader>().unwrap()),
128 BlockHeader {
129 last_block: false,
130 block_type: 4,
131 block_size: 122
132 }
133 );
134
135 assert_eq!(
137 dbg!(reader.parse::<VorbisComment>().unwrap()),
138 VorbisComment {
139 vendor: "reference libFLAC 1.1.4 20070213".to_string(),
140 comment: vec![
141 "title=2ch 44100 16bit".to_string(),
142 "album=Test Album".to_string(),
143 "artist=Assorted".to_string(),
144 "tracknumber=1".to_string(),
145 ],
146 }
147 );
148}