]> git.nihav.org Git - nihav.git/blame - nihav-game/src/codecs/lhst500f22.rs
nihav_registry: fix clippy warnings and tests in detect module
[nihav.git] / nihav-game / src / codecs / lhst500f22.rs
CommitLineData
3e52414f
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitreader::*;
12cf91ea 3use nihav_codec_support::dsp::qmf::QMF;
3e52414f
KS
4use std::str::FromStr;
5use std::sync::Arc;
6
7const CODEC_SAMPLES: usize = 1152;
8
3e52414f
KS
9struct 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
24impl 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 }
7450554d 104 #[allow(clippy::identity_op)]
3e52414f
KS
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
156impl 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);
7450554d 160 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
3e52414f
KS
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 (&mut 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
7d57ae2f
KS
210impl 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
3e52414f
KS
216pub fn get_decoder() -> Box<dyn NADecoder + Send> {
217 Box::new(LHDecoder::new())
218}
219
220const 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
225const 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];
235const 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];
245const 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
256const 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];
266const 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];
271const 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];
276const 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
292const QUANTS3: [f32; 4] = [ -1.0, -0.5, 0.0, 0.5 ];
293const QUANTS5: [f32; 6] = [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25 ];
294const QUANTS7: [f32; 8] = [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 ];
295const 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 ];
298const 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