add nihav-llaudio crate with FLAC, Monkey's Audio, TTA and WavPack support
[nihav.git] / nihav-llaudio / src / demuxers / flac.rs
1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
3
4 struct FLACDemuxer<'a> {
5 src: &'a mut ByteReader<'a>,
6 data_start: u64,
7 tot_samples: u64,
8 cur_samples: u64,
9 blk_samples: u16,
10 min_size: usize,
11 max_size: usize,
12 }
13
14 impl<'a> FLACDemuxer<'a> {
15 fn new(io: &'a mut ByteReader<'a>) -> Self {
16 Self {
17 src: io,
18 data_start: 0,
19 tot_samples: 0,
20 cur_samples: 0,
21 blk_samples: 0,
22 min_size: 0,
23 max_size: 0,
24 }
25 }
26 }
27
28 fn update_crc16(crc: u16, byte: u8) -> u16 {
29 (crc << 8) ^ CRC16_TABLE[(((crc >> 8) as u8) ^ byte) as usize]
30 }
31
32 fn read_utf8(src: &[u8]) -> DemuxerResult<u32> {
33 if (src[0] & 0x80) == 0 {
34 return Ok(u32::from(src[0]));
35 }
36 let len = (!src[0]).leading_zeros() as usize;
37 validate!(len != 1 && len <= 5 && src.len() >= len);
38 let mut val = u32::from(src[0] & 0x1F);
39 for byte in src.iter().take(len).skip(1) {
40 validate!((*byte & 0xC0) == 0x80);
41 val = (val << 6) | u32::from(*byte & 0x3F);
42 }
43 Ok(val)
44 }
45
46 impl<'a> DemuxCore<'a> for FLACDemuxer<'a> {
47 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
48 let tag = self.src.read_tag()?;
49 validate!(&tag == b"fLaC");
50 let mut streaminfo: Vec<u8> = Vec::new();
51 let mut srate = 0u32;
52 let mut channels = 0u8;
53 loop {
54 let id1 = self.src.read_byte()?;
55 let len = self.src.read_u24be()? as usize;
56 let id = id1 & 0x7F;
57
58 match id {
59 0x00 => {
60 validate!(len >= 34);
61 streaminfo = vec![0u8; len];
62 self.src.read_buf(&mut streaminfo)?;
63 let min_bs = read_u16be(&streaminfo[0..])?;
64 let max_bs = read_u16be(&streaminfo[2..])?;
65 if min_bs == max_bs {
66 self.blk_samples = max_bs;
67 }
68 self.min_size = read_u24be(&streaminfo[4..])? as usize;
69 self.max_size = read_u24be(&streaminfo[7..])? as usize;
70 let word = read_u24be(&streaminfo[10..])?;
71 srate = word >> 4;
72 channels = (((word >> 1) & 7) + 1) as u8;
73 self.tot_samples = (u64::from(streaminfo[13] & 0xF) << 32) | u64::from(read_u32be(&streaminfo[14..])?);
74 },
75 0x03 => {
76 validate!((len % 18) == 0);
77 seek_index.mode = SeekIndexMode::Present;
78 for _ in 0..len / 18 {
79 let sample = self.src.read_u64be()?;
80 let offset = self.src.read_u64be()?;
81 let _nsamps = self.src.read_u16be()?;
82 let time = sample * 1000 / u64::from(srate.max(1000));
83 seek_index.add_entry(0, SeekEntry { time, pts: sample, pos: offset });
84 }
85 },
86 _ => self.src.read_skip(len)?,
87 };
88
89 if (id1 & 0x80) != 0 {
90 break;
91 }
92 }
93 self.data_start = self.src.tell();
94 validate!(srate != 0);
95
96 let base = if self.blk_samples != 0 { u32::from(self.blk_samples) } else { 1 };
97 let ahdr = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, base as usize);
98 let ainfo = NACodecInfo::new("flac", NACodecTypeInfo::Audio(ahdr), Some(streaminfo));
99 strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, base, srate)).unwrap();
100
101 Ok(())
102 }
103 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
104 if self.src.is_eof() || (self.tot_samples != 0 && self.cur_samples == self.tot_samples) { return Err(DemuxerError::EOF); }
105 let mut buf = Vec::with_capacity(self.min_size);
106 let mut crc = 0;
107 for _ in 0..5 {
108 let byte = self.src.read_byte()?;
109 buf.push(byte);
110 crc = update_crc16(crc, byte);
111 }
112 let mut ref_crc = self.src.read_u16be()?;
113 loop {
114 let byte = self.src.read_byte()?;
115 let old_byte = (ref_crc >> 8) as u8;
116 buf.push(old_byte);
117 ref_crc = (ref_crc << 8) | u16::from(byte);
118 crc = update_crc16(crc, old_byte);
119 if buf.len() + 2 >= self.min_size && crc == ref_crc {
120 let ret = self.src.peek_u16be();
121 if ret.is_err() || ((ret.unwrap_or(0) & 0xFFFE) == 0xFFF8) {
122 buf.push((ref_crc >> 8) as u8);
123 buf.push(ref_crc as u8);
124 break;
125 }
126 }
127 if (self.max_size > 0) && (buf.len() > self.max_size) {
128 return Err(DemuxerError::InvalidData);
129 }
130 if buf.len() > (1 << 23) {
131 return Err(DemuxerError::InvalidData);
132 }
133 }
134
135 let (duration, pts) = if self.blk_samples != 0 {
136 validate!((buf[1] & 1) == 0);
137 let blkno = u64::from(read_utf8(&buf[4..])?);
138 self.cur_samples = blkno * u64::from(self.blk_samples);
139 (u64::from(self.blk_samples), blkno)
140 } else {
141 validate!((buf[1] & 1) != 0);
142 let blksamps = u64::from(read_utf8(&buf[4..])?);
143 (blksamps, self.cur_samples)
144 };
145
146 let stream = strmgr.get_stream(0).unwrap();
147 let (tb_num, tb_den) = stream.get_timebase();
148 let ts = NATimeInfo::new(Some(pts), None, Some(duration), tb_num, tb_den);
149 let pkt = NAPacket::new(stream, ts, true, buf);
150
151 self.cur_samples += duration;
152
153 Ok(pkt)
154 }
155 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
156 let ret = seek_index.find_pos(time);
157 if ret.is_none() {
158 return Err(DemuxerError::SeekError);
159 }
160 let seek_info = ret.unwrap();
161 self.cur_samples = seek_info.pts;
162 self.src.seek(SeekFrom::Start(self.data_start + seek_info.pos))?;
163
164 Ok(())
165 }
166 }
167
168 impl<'a> NAOptionHandler for FLACDemuxer<'a> {
169 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
170 fn set_options(&mut self, _options: &[NAOption]) { }
171 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
172 }
173
174 pub struct FLACDemuxerCreator { }
175
176 impl DemuxerCreator for FLACDemuxerCreator {
177 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
178 Box::new(FLACDemuxer::new(br))
179 }
180 fn get_name(&self) -> &'static str { "flac" }
181 }
182
183 #[cfg(test)]
184 mod test {
185 use super::*;
186 use std::fs::File;
187
188 #[test]
189 fn test_flac_demux() {
190 let mut file = File::open("assets/LLaudio/luckynight.flac").unwrap();
191 let mut fr = FileReader::new_read(&mut file);
192 let mut br = ByteReader::new(&mut fr);
193 let mut dmx = FLACDemuxer::new(&mut br);
194 let mut sm = StreamManager::new();
195 let mut si = SeekIndex::new();
196 dmx.open(&mut sm, &mut si).unwrap();
197 loop {
198 let pktres = dmx.get_frame(&mut sm);
199 if let Err(e) = pktres {
200 if (e as i32) == (DemuxerError::EOF as i32) { break; }
201 panic!("error");
202 }
203 let pkt = pktres.unwrap();
204 println!("Got {}", pkt);
205 }
206 }
207 }
208
209 const CRC16_TABLE: [u16; 256] = [
210 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
211 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
212 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
213 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
214 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
215 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
216 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
217 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
218 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
219 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
220 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
221 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
222 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
223 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
224 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
225 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
226 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
227 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
228 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
229 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
230 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
231 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
232 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
233 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
234 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
235 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
236 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
237 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
238 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
239 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
240 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
241 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
242 ];