add LinePack decoder
[nihav.git] / nihav-game / src / codecs / lhst500f22.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_codec_support::dsp::qmf::QMF;
4 use std::str::FromStr;
5 use std::sync::Arc;
6
7 const CODEC_SAMPLES: usize = 1152;
8
9 struct LHDecoder {
10 ainfo: NAAudioInfo,
11 info: Arc<NACodecInfo>,
12 chmap: NAChannelMap,
13
14 bitalloc: [[u8; 32]; 3],
15 scf_select: [u8; 32],
16 scales: [[u8; 32]; 3],
17 samples: [[f32; 32]; 36],
18
19 bitpos: u32,
20
21 qmf: QMF,
22 }
23
24 impl LHDecoder {
25 fn new() -> Self {
26 Self {
27 ainfo: NAAudioInfo::new(22050, 1, SND_F32P_FORMAT, CODEC_SAMPLES),
28 info: NACodecInfo::new_dummy(),
29 chmap: NAChannelMap::new(),
30
31 bitalloc: [[0; 32]; 3],
32 scf_select: [0; 32],
33 scales: [[0; 32]; 3],
34 samples: [[0.0; 32]; 36],
35
36 bitpos: 0,
37
38 qmf: QMF::new(),
39 }
40 }
41 fn unpack_bitalloc(&mut self, br: &mut BitReader) -> DecoderResult<()> {
42 for i in 0..3 {
43 for sb in 0..32 {
44 self.bitalloc[i][sb] = br.read(BITALLOC_INFO[sb])? as u8;
45 }
46 }
47 Ok(())
48 }
49 fn unpack_scales(&mut self, br: &mut BitReader) -> DecoderResult<()> {
50 for sb in 0..32 {
51 if (self.bitalloc[0][sb] | self.bitalloc[1][sb] | self.bitalloc[2][sb]) != 0 {
52 self.scf_select[sb] = br.read(2)? as u8;
53 } else {
54 self.scf_select[sb] = 0;
55 }
56 }
57
58 self.scales = [[0; 32]; 3];
59 for sb in 0..32 {
60 let ba0 = self.bitalloc[0][sb];
61 let ba1 = self.bitalloc[1][sb];
62 let ba2 = self.bitalloc[2][sb];
63 if (ba0 | ba1 | ba2) == 0 {
64 continue;
65 }
66 match self.scf_select[sb] {
67 0 => {
68 for j in 0..3 {
69 if self.bitalloc[j][sb] != 0 {
70 self.scales[j][sb] = br.read(6)? as u8;
71 }
72 }
73 },
74 1 => {
75 if (ba0 | ba1) != 0 {
76 let scale = br.read(6)? as u8;
77 self.scales[0][sb] = scale;
78 self.scales[1][sb] = scale;
79 }
80 if ba2 != 0 {
81 self.scales[2][sb] = br.read(6)? as u8;
82 }
83 },
84 2 => {
85 let scale = br.read(6)? as u8;
86 self.scales[0][sb] = scale;
87 self.scales[1][sb] = scale;
88 self.scales[2][sb] = scale;
89 },
90 _ => {
91 if ba0 != 0 {
92 self.scales[0][sb] = br.read(6)? as u8;
93 }
94 if (ba1 | ba2) != 0 {
95 let scale = br.read(6)? as u8;
96 self.scales[1][sb] = scale;
97 self.scales[2][sb] = scale;
98 }
99 },
100 };
101 }
102 Ok(())
103 }
104 #[allow(clippy::identity_op)]
105 fn unpack_samples(&mut self, br: &mut BitReader) -> DecoderResult<()> {
106 for grp in 0..3 {
107 for gr in 0..4 {
108 for sb in 0..32 {
109 let set = (grp * 4 + gr) * 3;
110 if self.bitalloc[grp][sb] == 0 {
111 self.samples[set + 0][sb] = 0.0;
112 self.samples[set + 1][sb] = 0.0;
113 self.samples[set + 2][sb] = 0.0;
114 continue;
115 }
116 let idx = sb * 4 + (self.bitalloc[grp][sb] as usize);
117 let bits = GROUP_BITS[idx];
118 let sf = SCALEFACTORS[self.scales[grp][sb] as usize];
119 if GROUP_INFO[idx] == 1 {
120 let radix = (1 << bits) - 1;
121 let val0 = br.read(bits)? as usize;
122 let val1 = br.read(bits)? as usize;
123 let val2 = br.read(bits)? as usize;
124 self.samples[set + 0][sb] = Self::dequant(val0, idx, radix) * sf;
125 self.samples[set + 1][sb] = Self::dequant(val1, idx, radix) * sf;
126 self.samples[set + 2][sb] = Self::dequant(val2, idx, radix) * sf;
127 } else {
128 let radix = GROUP_RADIX[idx] as usize;
129 let val = br.read(bits)? as usize;
130 let val0 = val % radix;
131 let val1 = (val / radix) % radix;
132 let val2 = val / radix / radix;
133 self.samples[set + 0][sb] = Self::dequant(val0, idx, radix) * sf;
134 self.samples[set + 1][sb] = Self::dequant(val1, idx, radix) * sf;
135 self.samples[set + 2][sb] = Self::dequant(val2, idx, radix) * sf;
136 }
137 }
138 }
139 }
140 Ok(())
141 }
142 fn dequant(val: usize, idx: usize, radix: usize) -> f32 {
143 let qval = match radix {
144 3 => QUANTS3[val],
145 5 => QUANTS5[val],
146 7 => QUANTS7[val],
147 15 => QUANTS15[val],
148 63 => QUANTS63[val],
149 _ => unreachable!(),
150 };
151 let bias_idx = QUANT_BIAS_MAP[idx] as usize;
152 (qval + QUANT_BIAS[bias_idx]) / QUANT_RANGE[bias_idx]
153 }
154 }
155
156 impl NADecoder for LHDecoder {
157 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
158 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
159 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_F32P_FORMAT, CODEC_SAMPLES);
160 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
161 self.chmap = NAChannelMap::from_str("C").unwrap();
162 Ok(())
163 } else {
164 Err(DecoderError::InvalidData)
165 }
166 }
167 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
168 let info = pkt.get_stream().get_info();
169 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
170 let pktbuf = pkt.get_buffer();
171
172 let mut daudio = Vec::with_capacity(CODEC_SAMPLES);
173
174 let mut br = BitReader::new(pktbuf.as_slice(), BitReaderMode::BE);
175 br.skip(self.bitpos)?;
176
177 while br.left() >= 8 {
178 self.unpack_bitalloc(&mut br)?;
179 self.unpack_scales(&mut br)?;
180 self.unpack_samples(&mut br)?;
181
182 let mut samp_buf = [0.0f32; 32];
183 for set in 0..36 {
184 self.qmf.synth(&self.samples[set], &mut samp_buf);
185 daudio.extend_from_slice(&samp_buf);
186 }
187 }
188
189 self.bitpos = (br.tell() as u32) & 7;
190
191 let abuf = alloc_audio_buffer(self.ainfo, daudio.len(), self.chmap.clone())?;
192 let mut adata = abuf.get_abuf_f32().unwrap();
193 let buf = adata.get_data_mut().unwrap();
194 buf[..daudio.len()].copy_from_slice(daudio.as_slice());
195
196 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
197 frm.set_duration(Some(CODEC_SAMPLES as u64));
198 frm.set_keyframe(true);
199 Ok(frm.into_ref())
200 } else {
201 Err(DecoderError::Bug)
202 }
203 }
204 fn flush(&mut self) {
205 self.qmf = QMF::new();
206 self.bitpos = 0;
207 }
208 }
209
210 impl NAOptionHandler for LHDecoder {
211 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
212 fn set_options(&mut self, _options: &[NAOption]) { }
213 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
214 }
215
216 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
217 Box::new(LHDecoder::new())
218 }
219
220 const BITALLOC_INFO: [u8; 32] = [
221 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
222 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
223 ];
224
225 const GROUP_BITS: [u8; 128] = [
226 0, 3, 4, 6, 0, 3, 4, 6, 0, 3, 4, 6, 0, 3, 4, 6,
227 0, 3, 4, 6, 0, 3, 4, 6, 0, 5, 7, 4, 0, 5, 7, 4,
228 0, 5, 7, 4, 0, 5, 7, 4, 0, 5, 7, 4, 0, 5, 7, 4,
229 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0,
230 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0,
231 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0,
232 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0,
233 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0
234 ];
235 const GROUP_INFO: [u8; 128] = [
236 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1,
237 0, 1, 1, 1, 0, 1, 1, 1, 0, 3, 3, 1, 0, 3, 3, 1,
238 0, 3, 3, 1, 0, 3, 3, 1, 0, 3, 3, 1, 0, 3, 3, 1,
239 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
240 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
241 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
242 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
243 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0
244 ];
245 const GROUP_RADIX: [u8; 128] = [
246 0, 7, 15, 63, 0, 7, 15, 63, 0, 7, 15, 63, 0, 7, 15, 63,
247 0, 7, 15, 63, 0, 7, 15, 63, 0, 3, 5, 15, 0, 3, 5, 15,
248 0, 3, 5, 15, 0, 3, 5, 15, 0, 3, 5, 15, 0, 3, 5, 15,
249 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
250 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
251 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
252 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
253 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0
254 ];
255
256 const QUANT_BIAS_MAP: [u8; 128] = [
257 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6,
258 0, 2, 4, 6, 0, 2, 4, 6, 0, 0, 1, 4, 0, 0, 1, 4,
259 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 1, 4,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
265 ];
266 const QUANT_BIAS: [f32; 17] = [
267 0.5, 0.5, 0.25, 0.5, 0.125, 0.0625, 0.03125, 0.015625,
268 0.0078125, 0.00390625, 0.001953125, 0.0009765625, 0.00048828125,
269 0.00024414062, 0.00012207031, 0.000061035164, 0.000030517582
270 ];
271 const QUANT_RANGE: [f32; 17] = [
272 0.75, 0.625, 0.875, 0.5625, 0.9375, 0.96875, 0.984375,
273 0.9921875, 0.99609375, 0.99804688, 0.99902344, 0.99951172,
274 0.99975586, 0.99987793, 0.99993896, 0.99996948, 0.99998474
275 ];
276 const SCALEFACTORS: [f32; 64] = [
277 2.0, 1.587401, 1.2599211, 1.0, 0.79370052, 0.62996054,
278 0.5, 0.39685026, 0.31498027, 0.25, 0.19842513, 0.15749013,
279 0.125, 0.099212565, 0.078745067, 0.0625, 0.049606282, 0.039372534,
280 0.03125, 0.024803141, 0.019686267, 0.015625, 0.012401571, 0.0098431334,
281 0.0078125, 0.0062007853, 0.0049215667, 0.00390625, 0.0031003926, 0.0024607833,
282 0.001953125, 0.0015501963, 0.0012303917, 0.0009765625, 0.00077509816, 0.00061519584,
283 0.00048828125, 0.00038754908, 0.00030759792, 0.00024414062, 0.00019377454, 0.00015379896,
284 0.00012207031, 0.00009688727, 0.00007689948, 0.000061035156,
285 0.000048443635, 0.00003844974, 0.000030517578, 0.000024221818,
286 0.00001922487, 0.000015258789, 0.000012110909, 0.000009612435,
287 0.0000076293945, 0.0000060554544, 0.0000048062175, 0.0000038146973,
288 0.0000030277272, 0.0000024031087, 0.0000019073486, 0.0000015138636,
289 0.0000012015544, 9.9999997e-21
290 ];
291
292 const QUANTS3: [f32; 4] = [ -1.0, -0.5, 0.0, 0.5 ];
293 const QUANTS5: [f32; 6] = [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25 ];
294 const QUANTS7: [f32; 8] = [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 ];
295 const QUANTS15: [f32; 16] = [
296 -1.0, -0.875, -0.75, -0.625, -0.5, -0.375, -0.25, -0.125,
297 0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 ];
298 const QUANTS63: [f32; 64] = [
299 -1.0, -0.96875, -0.9375, -0.90625, -0.875, -0.84375, -0.8125, -0.78125,
300 -0.75, -0.71875, -0.6875, -0.65625, -0.625, -0.59375, -0.5625, -0.53125,
301 -0.5, -0.46875, -0.4375, -0.40625, -0.375, -0.34375, -0.3125, -0.28125,
302 -0.25, -0.21875, -0.1875, -0.15625, -0.125, -0.09375, -0.0625, -0.03125,
303 0.0, 0.03125, 0.0625, 0.09375, 0.125, 0.15625, 0.1875, 0.21875,
304 0.25, 0.28125, 0.3125, 0.34375, 0.375, 0.40625, 0.4375, 0.46875,
305 0.5, 0.53125, 0.5625, 0.59375, 0.625, 0.65625, 0.6875, 0.71875,
306 0.75, 0.78125, 0.8125, 0.84375, 0.875, 0.90625, 0.9375, 0.96875 ];
307