Flash support
[nihav.git] / nihav-flash / src / codecs / asao.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_codec_support::dsp::mdct::*;
4 use nihav_codec_support::dsp::window::*;
5
6 struct Random { state: u32 }
7
8 impl Random {
9 fn new(seed: u32) -> Self { Self { state: seed } }
10 fn next(&mut self) -> u32 {
11 self.state ^= self.state << 13;
12 self.state ^= self.state >> 17;
13 self.state ^= self.state << 5;
14 self.state
15 }
16 }
17
18 const NUM_BANDS: usize = 23;
19 const BLOCK_LEN: usize = 256;
20 const PACKED_BLK_LEN: usize = 64;
21 const CODED_LEN: usize = 124;
22
23 struct ASAODecoder {
24 ainfo: NAAudioInfo,
25 chmap: NAChannelMap,
26 window: [f32; 128],
27 imdct: IMDCT,
28 rng: Random,
29
30 scales: [f32; 128],
31 iscales: [i32; 128],
32 bits: [i8; 128],
33 coeffs: [f32; 128],
34 prev: [f32; 128],
35 tmp: [f32; 128],
36 }
37
38 const HEADER_BITS: u32 = 116;
39 const SUBPART_BITS: i32 = (((PACKED_BLK_LEN as u32) * 8 - HEADER_BITS) / 2) as i32;
40 const MAX_CBITS: i32 = 6;
41 const BASE_OFF: i32 = 4228;
42 const BASE_SHIFT: i8 = 19;
43
44 trait SignedShift {
45 type Output;
46 fn sshift(self, shift: i8) -> Self::Output;
47 }
48
49 impl SignedShift for i32 {
50 type Output = Self;
51 fn sshift(self, shift: i8) -> Self::Output {
52 if shift >= 0 {
53 self << shift
54 } else {
55 self >> -shift
56 }
57 }
58 }
59
60 fn norm(val: &mut i32) -> i8 {
61 if *val == 0 {
62 31
63 } else {
64 let shift = val.abs().leading_zeros() - 1;
65 *val <<= shift;
66 shift as i8
67 }
68 }
69
70 fn sum_bits(src: &[i32; 128], shift: i8, off: i32) -> i32 {
71 let mut sum = 0;
72 for &el in src[..CODED_LEN].iter() {
73 let val = (((el - off) >> (shift - 1)) + 1) >> 1;
74 sum += val.max(0).min(MAX_CBITS);
75 }
76 sum
77 }
78
79 fn bitalloc(bits: &mut [i8; 128], scales: &[i32; 128]) {
80 let mut max = scales[..CODED_LEN].iter().fold(scales[0], |v, &x| v.max(x));
81 let mut shift = norm(&mut max) - 16;
82
83 let mut tmp = [0; 128];
84 let mut sum = 0;
85 for i in 0..CODED_LEN {
86 tmp[i] = (scales[i].sshift(shift) * 3) >> 2;
87 sum += tmp[i];
88 }
89
90 shift += 11;
91 let ref_shift = shift;
92
93 sum -= SUBPART_BITS << shift;
94 shift += norm(&mut sum);
95 shift = ref_shift - (BASE_SHIFT + shift - 31);
96 let mut offset = ((BASE_OFF * (sum >> 16)) >> 15).sshift(shift);
97
98 let mut bitsum = sum_bits(&tmp, ref_shift, offset);
99
100 if bitsum != SUBPART_BITS {
101 let mut off2 = bitsum - SUBPART_BITS;
102 shift = 0;
103 while off2.abs() <= 0x3FFF {
104 off2 <<= 1;
105 shift += 1;
106 }
107
108 shift = ref_shift - (BASE_SHIFT + shift - 15);
109 off2 = ((BASE_OFF * off2) >> 15).sshift(shift);
110
111 let mut last_off = 0;
112 let mut last_bitsum = 0;
113 let mut iter = 1;
114 while iter < 20 {
115 last_off = offset;
116 offset += off2;
117 last_bitsum = bitsum;
118 bitsum = sum_bits(&tmp, ref_shift, offset);
119 if (bitsum - SUBPART_BITS) * (last_bitsum - SUBPART_BITS) <= 0 {
120 break;
121 }
122 iter += 1;
123 }
124
125 let (mut big_off, mut small_off, mut big_sum, mut small_sum) = if bitsum > SUBPART_BITS {
126 (offset, last_off, bitsum, last_bitsum)
127 } else {
128 (last_off, offset, last_bitsum, bitsum)
129 };
130
131 while bitsum != SUBPART_BITS && iter < 20 {
132 let off = (big_off + small_off) >> 1;
133 bitsum = sum_bits(&tmp, ref_shift, off);
134 if bitsum > SUBPART_BITS {
135 big_off = off;
136 big_sum = bitsum;
137 } else {
138 small_off = off;
139 small_sum = bitsum;
140 }
141 iter += 1;
142 }
143
144 if (big_sum - SUBPART_BITS).abs() >= (small_sum - SUBPART_BITS).abs() {
145 offset = small_off;
146 bitsum = small_sum;
147 } else {
148 offset = big_off;
149 bitsum = big_sum;
150 }
151 }
152
153 for (bits, &val) in bits.iter_mut().zip(tmp.iter()).take(CODED_LEN) {
154 *bits = ((((val - offset) >> (ref_shift - 1)) + 1) >> 1).max(0).min(MAX_CBITS) as i8;
155 }
156 if bitsum > SUBPART_BITS {
157 let mut sum = 0;
158 let mut i = 0;
159 while sum < SUBPART_BITS {
160 sum += i32::from(bits[i]);
161 i += 1;
162 }
163 bits[i - 1] -= (sum - SUBPART_BITS) as i8;
164 while i < CODED_LEN {
165 bits[i] = 0;
166 i += 1;
167 }
168 }
169 }
170
171 fn overlap_add(dst: &mut [f32], src: &[f32; 128], prev: &[f32; 128], window: &[f32; 128]) {
172 for i in 0..64 {
173 let p = prev[64 + i];
174 let s = src [63 - i];
175 let w0 = window[i];
176 let w1 = window[127 - i];
177 dst[i] = p * w1 - s * w0;
178 dst[127 - i] = p * w0 + s * w1;
179 }
180 }
181
182 impl ASAODecoder {
183 fn new() -> Self {
184 let mut window = [0.0; 128];
185 generate_window(WindowType::Sine, 1.0/1024.0, 128, true, &mut window);
186
187 Self {
188 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, BLOCK_LEN),
189 chmap: NAChannelMap::new(),
190 window,
191 imdct: IMDCT::new(256, true),
192 rng: Random::new(42),
193
194 scales: [0.0; 128],
195 iscales: [0; 128],
196 bits: [0; 128],
197 coeffs: [0.0; 128],
198 prev: [0.0; 128],
199 tmp: [0.0; 128],
200 }
201 }
202 fn decode_block(&mut self, br: &mut BitReader, dst: &mut [f32]) -> DecoderResult<()> {
203 let mut scale = i32::from(SCALE[br.read(6)? as usize]);
204 let mut sc_iter = self.scales.iter_mut();
205 let mut isc_iter = self.iscales.iter_mut();
206 for (band, &band_size) in BAND_SIZES.iter().enumerate() {
207 if band > 0 {
208 scale += i32::from(SCALE_DIFF[br.read(5)? as usize]);
209 }
210 let scf = -(2.0f32.powf((scale as f32) / 2048.0));
211 for _ in 0..band_size {
212 *sc_iter.next().unwrap() = scf;
213 *isc_iter.next().unwrap() = scale;
214 }
215 }
216
217 bitalloc(&mut self.bits, &self.iscales);
218
219 let mut coeffs = &mut self.coeffs;
220 let mut prev = &mut self.prev;
221 for (i, out) in dst.chunks_exact_mut(BLOCK_LEN / 2).take(2).enumerate() {
222 br.seek(HEADER_BITS + (SUBPART_BITS as u32) * (i as u32))?;
223 for j in 0..CODED_LEN {
224 if self.bits[j] <= 0 {
225 self.tmp[j] = std::f32::consts::FRAC_1_SQRT_2;
226 if (self.rng.next() & 1) != 0 {
227 self.tmp[j] = -self.tmp[j];
228 }
229 } else {
230 let val = br.read(self.bits[j] as u8)? as usize;
231 self.tmp[j] = QUANT_VALS[self.bits[j] as usize][val];
232 }
233 self.tmp[j] *= self.scales[j];
234 }
235 for j in CODED_LEN..128 {
236 self.tmp[j] = 0.0;
237 }
238 self.imdct.imdct_half(&self.tmp, coeffs);
239 overlap_add(out, coeffs, prev, &self.window);
240 std::mem::swap(&mut coeffs, &mut prev);
241 }
242
243 Ok(())
244 }
245 }
246
247
248 impl NADecoder for ASAODecoder {
249 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
250 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
251 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_F32P_FORMAT, BLOCK_LEN);
252 self.chmap = NAChannelMap::new();
253 self.chmap.add_channel(NAChannelType::C);
254 Ok(())
255 } else {
256 Err(DecoderError::InvalidData)
257 }
258 }
259 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
260 let info = pkt.get_stream().get_info();
261 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
262 let src = pkt.get_buffer();
263
264 validate!((src.len() % PACKED_BLK_LEN) == 0);
265 let npkts = src.len() / PACKED_BLK_LEN;
266 let nsamples = npkts * BLOCK_LEN;
267 let abuf = alloc_audio_buffer(self.ainfo, nsamples, self.chmap.clone())?;
268 let mut adata = abuf.get_abuf_f32().unwrap();
269 let dst = adata.get_data_mut().unwrap();
270
271 for (src, dst) in src.chunks_exact(PACKED_BLK_LEN).zip(dst.chunks_mut(BLOCK_LEN)) {
272 let mut br = BitReader::new(&src, BitReaderMode::LE);
273 self.decode_block(&mut br, dst)?;
274 }
275
276 let mut frm = NAFrame::new_from_pkt(pkt, info.replace_info(NACodecTypeInfo::Audio(self.ainfo)), abuf);
277 frm.set_duration(Some(nsamples as u64));
278 frm.set_keyframe(true);
279 Ok(frm.into_ref())
280 } else {
281 Err(DecoderError::InvalidData)
282 }
283 }
284 fn flush(&mut self) {
285 }
286 }
287
288 impl NAOptionHandler for ASAODecoder {
289 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
290 fn set_options(&mut self, _options: &[NAOption]) { }
291 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
292 }
293
294 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
295 Box::new(ASAODecoder::new())
296 }
297
298 #[cfg(test)]
299 mod test {
300 use nihav_core::codecs::RegisteredDecoders;
301 use nihav_core::demuxers::RegisteredDemuxers;
302 use nihav_codec_support::test::dec_video::*;
303 use crate::flash_register_all_decoders;
304 use crate::flash_register_all_demuxers;
305 #[test]
306 fn test_asao() {
307 let mut dmx_reg = RegisteredDemuxers::new();
308 flash_register_all_demuxers(&mut dmx_reg);
309 let mut dec_reg = RegisteredDecoders::new();
310 flash_register_all_decoders(&mut dec_reg);
311
312 test_decode_audio("flv", "assets/Flash/nellymoser-in-flv.flv", Some(3000), None/*Some("asao")*/, &dmx_reg, &dec_reg);
313 }
314 }
315
316 #[allow(clippy::excessive_precision)]
317 const QUANT_VALS: [&[f32]; 7] = [
318 &[ 0.0000000000 ],
319 &[ -0.8472560048, 0.7224709988 ],
320 &[ -1.5247479677, -0.4531480074, 0.3753609955, 1.4717899561 ],
321 &[ -1.9822579622, -1.1929379702, -0.5829370022, -0.0693780035,
322 0.3909569979, 0.9069200158, 1.4862740040, 2.2215409279 ],
323 &[ -2.3887870312, -1.8067539930, -1.4105420113, -1.0773609877,
324 -0.7995010018, -0.5558109879, -0.3334020078, -0.1324490011,
325 0.0568020009, 0.2548770010, 0.4773550034, 0.7386850119,
326 1.0443060398, 1.3954459429, 1.8098750114, 2.3918759823 ],
327 &[ -2.3893830776, -1.9884680510, -1.7514040470, -1.5643119812,
328 -1.3922129869, -1.2164649963, -1.0469499826, -0.8905100226,
329 -0.7645580173, -0.6454579830, -0.5259280205, -0.4059549868,
330 -0.3029719889, -0.2096900046, -0.1239869967, -0.0479229987,
331 0.0257730000, 0.1001340002, 0.1737180054, 0.2585540116,
332 0.3522900045, 0.4569880068, 0.5767750144, 0.7003160119,
333 0.8425520062, 1.0093879700, 1.1821349859, 1.3534560204,
334 1.5320819616, 1.7332619429, 1.9722349644, 2.3978140354 ],
335 &[ -2.5756309032, -2.0573320389, -1.8984919786, -1.7727810144,
336 -1.6662600040, -1.5742180347, -1.4993319511, -1.4316639900,
337 -1.3652280569, -1.3000990152, -1.2280930281, -1.1588579416,
338 -1.0921250582, -1.0135740042, -0.9202849865, -0.8287050128,
339 -0.7374889851, -0.6447759867, -0.5590940118, -0.4857139885,
340 -0.4110319912, -0.3459700048, -0.2851159871, -0.2341620028,
341 -0.1870580018, -0.1442500055, -0.1107169986, -0.0739680007,
342 -0.0365610011, -0.0073290002, 0.0203610007, 0.0479039997,
343 0.0751969963, 0.0980999991, 0.1220389977, 0.1458999962,
344 0.1694349945, 0.1970459968, 0.2252430022, 0.2556869984,
345 0.2870100141, 0.3197099864, 0.3525829911, 0.3889069855,
346 0.4334920049, 0.4769459963, 0.5204820037, 0.5644530058,
347 0.6122040153, 0.6685929894, 0.7341650128, 0.8032159805,
348 0.8784040213, 0.9566209912, 1.0397069454, 1.1293770075,
349 1.2211159468, 1.3080279827, 1.4024800062, 1.5056819916,
350 1.6227730513, 1.7724959850, 1.9430880547, 2.2903931141 ]
351 ];
352
353 const SCALE_DIFF: [i16; 32] = [
354 -11725, -9420, -7910, -6801, -5948, -5233, -4599, -4039,
355 -3507, -3030, -2596, -2170, -1774, -1383, -1016, -660,
356 -329, -1, 337, 696, 1085, 1512, 1962, 2433,
357 2968, 3569, 4314, 5279, 6622, 8154, 10076, 12975
358 ];
359
360 const BAND_SIZES: [usize; NUM_BANDS] = [
361 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 12, 14, 15
362 ];
363
364 const SCALE: [u16; 64] = [
365 3134, 5342, 6870, 7792, 8569, 9185, 9744, 10191,
366 10631, 11061, 11434, 11770, 12116, 12513, 12925, 13300,
367 13674, 14027, 14352, 14716, 15117, 15477, 15824, 16157,
368 16513, 16804, 17090, 17401, 17679, 17948, 18238, 18520,
369 18764, 19078, 19381, 19640, 19921, 20205, 20500, 20813,
370 21162, 21465, 21794, 22137, 22453, 22756, 23067, 23350,
371 23636, 23926, 24227, 24521, 24819, 25107, 25414, 25730,
372 26120, 26497, 26895, 27344, 27877, 28463, 29426, 31355
373 ];