fix the rest of tests
[nihav.git] / nihav-realmedia / src / codecs / ra288.rs
CommitLineData
5641dccf
KS
1use std::rc::Rc;
2use std::cell::RefCell;
3use nihav_core::formats::*;
4use nihav_core::frame::*;
5use nihav_core::codecs::*;
6use nihav_core::io::bitreader::*;
37d2275e
KS
7const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C];
8const NBLOCKS: usize = 32;
9const BLOCKSIZE: usize = 5;
10const FRAME_SIZE: usize = 38;
11
12const SP_LPC_ORDER: usize = 36;
13const SP_START: usize = 70;
14const GAIN_LPC_ORDER: usize = 10;
15const GAIN_START: usize = 28;
16
17struct RA288Decoder {
18 chmap: NAChannelMap,
19 ainfo: NAAudioInfo,
20 info: Rc<NACodecInfo>,
21
22 speech_lpc: [f32; SP_LPC_ORDER],
23 speech_hist: [f32; 111],
24 speech_rec: [f32; SP_LPC_ORDER + 1],
25 gain_lpc: [f32; GAIN_LPC_ORDER],
26 gain_hist: [f32; GAIN_LPC_ORDER + GAIN_START],
27 gain_rec: [f32; GAIN_LPC_ORDER + 1],
28}
29
30const BF_ORDER: usize = SP_LPC_ORDER + 1;
31const BF_WORK_SIZE: usize = SP_LPC_ORDER + 40 + 35;
32
33fn backfilter(hist: &mut [f32], rec: &mut [f32], filt: &mut [f32], win: &[f32], bw_tab: &[f32], start: usize, non_rec: usize, move_size: usize) {
34 let mut temp: [f32; BF_ORDER] = [0.0; BF_ORDER];
35 let order = filt.len();
36
37 let mut tmp1: [f32; BF_ORDER] = [0.0; BF_ORDER];
38 let mut tmp2: [f32; BF_ORDER] = [0.0; BF_ORDER];
39 let mut work: [f32; BF_WORK_SIZE] = [0.0; BF_WORK_SIZE];
40 for i in 0..(order + start + non_rec) {
41 work[i] = win[i] * hist[i];
42 }
43 for i in (0..order + 1).rev() {
44 let src1 = &work[(order - i)..];
45 let src2 = &work[order + start - i..];
46 tmp1[i] = scalarprod(&work[order..], src1, start);
47 tmp2[i] = scalarprod(&work[order + start..], src2, non_rec);
48 }
49
50 for i in 0..(order + 1) {
51 rec[i] = rec[i] * 0.5625 + tmp1[i];
52 temp[i] = rec[i] + tmp2[i];
53 }
54 temp[0] *= 257.0 / 256.0;
55
56 if compute_lpc(&temp, filt) {
57 for (f, c) in filt.iter_mut().zip(bw_tab.iter()) {
58 *f *= c;
59 }
60 }
61 for i in 0..move_size {
62 hist[i] = hist[i + start];
63 }
64}
65
66fn scalarprod(src0: &[f32], src1: &[f32], len: usize) -> f32 {
67 let mut sum: f32 = 0.0;
68 for (a, b) in src0.iter().take(len).zip(src1.iter().take(len)) {
69 sum += *a * *b;
70 }
71 sum
72}
73
74fn compute_lpc(autoc: &[f32], filt: &mut [f32]) -> bool {
75 let order = filt.len();
76 let mut err = autoc[0];
77 if (err <= 0.0) || (autoc[order] == 0.0) {
78 return false;
79 }
80 for i in 0..order {
81 let mut r = -autoc[i + 1];
82 for j in 0..i {
83 r -= filt[j] * autoc[i - j];
84 }
85 r /= err;
86 err *= 1.0 - r * r;
87 filt[i] = r;
88
89 for j in 0..((i + 1) >> 1) {
90 let f = filt[j];
91 let b = filt[i - j - 1];
92 filt[j] = f + r * b;
93 filt[i - j - 1] = b + r * f;
94 }
95
96 if err < 0.0 { return false; }
97 }
98 true
99}
100
101fn celp_lp_synth_filter(dst: &mut [f32], start: usize, filt: &[f32], src: &[f32]) {
102 for (i, el) in src.iter().enumerate() {
103 dst[start + i] = *el;
104 for (j, coeff) in filt.iter().enumerate() {
105 dst[start + i] -= *coeff * dst[start + i - j - 1];
106 }
107 }
108}
109
110impl RA288Decoder {
111 fn new() -> Self {
112 RA288Decoder {
113 chmap: NAChannelMap::new(),
114 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, NBLOCKS * BLOCKSIZE),
115 info: NACodecInfo::new_dummy(),
116
117 speech_lpc: [0.0; SP_LPC_ORDER],
118 speech_hist: [0.0; 111],
119 speech_rec: [0.0; SP_LPC_ORDER + 1],
120 gain_lpc: [0.0; GAIN_LPC_ORDER],
121 gain_hist: [0.0; 38],
122 gain_rec: [0.0; GAIN_LPC_ORDER + 1],
123 }
124 }
125
126 fn process_subblock(&mut self, gain: f32, cb_idx: usize) {
127 for i in 0..SP_LPC_ORDER {
128 self.speech_hist[SP_START + i] = self.speech_hist[75 + i];
129 }
130 let mut sum: f32 = 32.0;
131 for i in 0..GAIN_LPC_ORDER {
132 sum -= self.gain_hist[GAIN_START + GAIN_LPC_ORDER - 1 - i] * self.gain_lpc[i];
133 }
134 sum = sum.max(0.0).min(60.0);
135
136 let scale = (sum * 0.1151292546497).exp() * gain * (1.0 / ((1 << 23) as f32));
137 let mut buf: [f32; BLOCKSIZE] = [0.0; BLOCKSIZE];
138 for i in 0..BLOCKSIZE {
139 buf[i] = (RA288_CODEBOOK[cb_idx][i] as f32) * scale;
140 }
141
142 let mut sum: f32 = 0.0;
143 for el in buf.iter() {
144 sum += *el * *el * (((1 << 24) as f32) / 5.0);
145 }
146 sum = sum.max(1.0);
147 for i in 0..(GAIN_LPC_ORDER - 1) {
148 self.gain_hist[GAIN_START + i] = self.gain_hist[GAIN_START + i + 1];
149 }
150 self.gain_hist[GAIN_START + GAIN_LPC_ORDER - 1] = 10.0 * sum.log10() - 32.0;
151 celp_lp_synth_filter(&mut self.speech_hist, SP_START + SP_LPC_ORDER, &self.speech_lpc, &buf);
152 }
153}
154
155impl NADecoder for RA288Decoder {
156 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
157 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
158 self.chmap.add_channels(&CHMAP_MONO);
159 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(),
160 1,
161 SND_F32P_FORMAT, NBLOCKS * BLOCKSIZE);
162 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo.clone()));
163 Ok(())
164 } else {
165 Err(DecoderError::InvalidData)
166 }
167 }
168 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
169 let info = pkt.get_stream().get_info();
170 validate!(info.get_properties().is_audio());
171 let pktbuf = pkt.get_buffer();
172 let nframes = pktbuf.len() / FRAME_SIZE;
173 let duration = NBLOCKS * BLOCKSIZE * nframes;
174
175 let mut abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
176 let mut adata = abuf.get_abuf_f32().unwrap();
177 let mut dst = adata.get_data_mut();
178
179 for (input, output) in pktbuf.chunks(FRAME_SIZE).zip(dst.chunks_mut(NBLOCKS * BLOCKSIZE)) {
180 let mut br = BitReader::new(input, input.len(), BitReaderMode::LE);
181
182 for (i, block) in output.chunks_mut(BLOCKSIZE).enumerate() {
183 let gain = RA288_GAIN_TAB[br.read(3)? as usize];
184 let cb = br.read((6 + (i & 1)) as u8)? as usize;
185
186 self.process_subblock(gain, cb);
187
188 for j in 0..BLOCKSIZE {
189 block[j] = self.speech_hist[SP_START + SP_LPC_ORDER + j];
190 }
191 if (i & 7) == 3 {
192 backfilter(&mut self.speech_hist, &mut self.speech_rec, &mut self.speech_lpc, RA288_SPEECH_WINDOW, RA288_SPEECH_BW_TAB, 40, 35, SP_START);
193 backfilter(&mut self.gain_hist, &mut self.gain_rec, &mut self.gain_lpc, RA288_GAIN_WINDOW, RA288_GAIN_BW_TAB, 8, 20, GAIN_START);
194 }
195 }
196 }
197
198 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
199 frm.set_keyframe(true);
200 Ok(Rc::new(RefCell::new(frm)))
201 }
202}
203
204pub fn get_decoder() -> Box<NADecoder> {
205 Box::new(RA288Decoder::new())
206}
207
208#[cfg(test)]
209mod test {
3167c45c
KS
210 use nihav_core::codecs::RegisteredDecoders;
211 use nihav_core::demuxers::RegisteredDemuxers;
212 use nihav_core::test::dec_video::*;
213 use crate::codecs::realmedia_register_all_codecs;
214 use crate::demuxers::realmedia_register_all_demuxers;
37d2275e
KS
215 #[test]
216 fn test_ra288() {
3167c45c
KS
217 let mut dmx_reg = RegisteredDemuxers::new();
218 realmedia_register_all_demuxers(&mut dmx_reg);
219 let mut dec_reg = RegisteredDecoders::new();
220 realmedia_register_all_codecs(&mut dec_reg);
221
37d2275e 222 let file = "assets/RV/A0000044.rm";
3167c45c 223 test_decode_audio("realmedia", file, Some(5000), "ra28.8", &dmx_reg, &dec_reg);
37d2275e
KS
224 }
225}
226
227const RA288_GAIN_TAB: [f32; 8] = [
228 0.515625, 0.90234375, 1.57910156, 2.76342773,
229 -0.515625, -0.90234375, -1.57910156, -2.76342773
230];
231
232const RA288_CODEBOOK: [[i16; 5]; 128] = [
233 [ 668, -2950, -1254, -1790, -2553], [ -5032, -4577, -1045, 2908, 3318],
234 [ -2819, -2677, -948, -2825, -4450], [ -6679, -340, 1482, -1276, 1262],
235 [ -562, -6757, 1281, 179, -1274], [ -2512, -7130, -4925, 6913, 2411],
236 [ -2478, -156, 4683, -3873, 0], [ -8208, 2140, -478, -2785, 533],
237 [ 1889, 2759, 1381, -6955, -5913], [ 5082, -2460, -5778, 1797, 568],
238 [ -2208, -3309, -4523, -6236, -7505], [ -2719, 4358, -2988, -1149, 2664],
239 [ 1259, 995, 2711, -2464,-10390], [ 1722, -7569, -2742, 2171, -2329],
240 [ 1032, 747, -858, -7946,-12843], [ 3106, 4856, -4193, -2541, 1035],
241 [ 1862, -960, -6628, 410, 5882], [ -2493, -2628, -4000, -60, 7202],
242 [ -2672, 1446, 1536, -3831, 1233], [ -5302, 6912, 1589, -4187, 3665],
243 [ -3456, -8170, -7709, 1384, 4698], [ -4699, -6209,-11176, 8104, 16830],
244 [ 930, 7004, 1269, -8977, 2567], [ 4649, 11804, 3441, -5657, 1199],
245 [ 2542, -183, -8859, -7976, 3230], [ -2872, -2011, -9713, -8385, 12983],
246 [ 3086, 2140, -3680, -9643, -2896], [ -7609, 6515, -2283, -2522, 6332],
247 [ -3333, -5620, -9130,-11131, 5543], [ -407, -6721,-17466, -2889, 11568],
248 [ 3692, 6796, -262,-10846, -1856], [ 7275, 13404, -2989,-10595, 4936],
249 [ 244, -2219, 2656, 3776, -5412], [ -4043, -5934, 2131, 863, -2866],
250 [ -3302, 1743, -2006, -128, -2052], [ -6361, 3342, -1583, -21, 1142],
251 [ -3837, -1831, 6397, 2545, -2848], [ -9332, -6528, 5309, 1986, -2245],
252 [ -4490, 748, 1935, -3027, -493], [ -9255, 5366, 3193, -4493, 1784],
253 [ 4784, -370, 1866, 1057, -1889], [ 7342, -2690, -2577, 676, -611],
254 [ -502, 2235, -1850, -1777, -2049], [ 1011, 3880, -2465, 2209, -152],
255 [ 2592, 2829, 5588, 2839, -7306], [ -3049, -4918, 5955, 9201, -4447],
256 [ 697, 3908, 5798, -4451, -4644], [ -2121, 5444, -2570, 321, -1202],
257 [ 2846, -2086, 3532, 566, -708], [ -4279, 950, 4980, 3749, 452],
258 [ -2484, 3502, 1719, -170, 238], [ -3435, 263, 2114, -2005, 2361],
259 [ -7338, -1208, 9347, -1216, -4013], [-13498, -439, 8028, -4232, 361],
260 [ -3729, 5433, 2004, -4727, -1259], [ -3986, 7743, 8429, -3691, -987],
261 [ 5198, -423, 1150, -1281, 816], [ 7409, 4109, -3949, 2690, 30],
262 [ 1246, 3055, -35, -1370, -246], [ -1489, 5635, -678, -2627, 3170],
263 [ 4830, -4585, 2008, -1062, 799], [ -129, 717, 4594, 14937, 10706],
264 [ 417, 2759, 1850, -5057, -1153], [ -3887, 7361, -5768, 4285, 666],
265 [ 1443, -938, 20, -2119, -1697], [ -3712, -3402, -2212, 110, 2136],
266 [ -2952, 12, -1568, -3500, -1855], [ -1315, -1731, 1160, -558, 1709],
267 [ 88, -4569, 194, -454, -2957], [ -2839, -1666, -273, 2084, -155],
268 [ -189, -2376, 1663, -1040, -2449], [ -2842, -1369, 636, -248, -2677],
269 [ 1517, 79, -3013, -3669, -973], [ 1913, -2493, -5312, -749, 1271],
270 [ -2903, -3324, -3756, -3690, -1829], [ -2913, -1547, -2760, -1406, 1124],
271 [ 1844, -1834, 456, 706, -4272], [ 467, -4256, -1909, 1521, 1134],
272 [ -127, -994, -637, -1491, -6494], [ 873, -2045, -3828, -2792, -578],
273 [ 2311, -1817, 2632, -3052, 1968], [ 641, 1194, 1893, 4107, 6342],
274 [ -45, 1198, 2160, -1449, 2203], [ -2004, 1713, 3518, 2652, 4251],
275 [ 2936, -3968, 1280, 131, -1476], [ 2827, 8, -1928, 2658, 3513],
276 [ 3199, -816, 2687, -1741, -1407], [ 2948, 4029, 394, -253, 1298],
277 [ 4286, 51, -4507, -32, -659], [ 3903, 5646, -5588, -2592, 5707],
278 [ -606, 1234, -1607, -5187, 664], [ -525, 3620, -2192, -2527, 1707],
279 [ 4297, -3251, -2283, 812, -2264], [ 5765, 528, -3287, 1352, 1672],
280 [ 2735, 1241, -1103, -3273, -3407], [ 4033, 1648, -2965, -1174, 1444],
281 [ 74, 918, 1999, 915, -1026], [ -2496, -1605, 2034, 2950, 229],
282 [ -2168, 2037, 15, -1264, -208], [ -3552, 1530, 581, 1491, 962],
283 [ -2613, -2338, 3621, -1488, -2185], [ -1747, 81, 5538, 1432, -2257],
284 [ -1019, 867, 214, -2284, -1510], [ -1684, 2816, -229, 2551, -1389],
285 [ 2707, 504, 479, 2783, -1009], [ 2517, -1487, -1596, 621, 1929],
286 [ -148, 2206, -4288, 1292, -1401], [ -527, 1243, -2731, 1909, 1280],
287 [ 2149, -1501, 3688, 610, -4591], [ 3306, -3369, 1875, 3636, -1217],
288 [ 2574, 2513, 1449, -3074, -4979], [ 814, 1826, -2497, 4234, -4077],
289 [ 1664, -220, 3418, 1002, 1115], [ 781, 1658, 3919, 6130, 3140],
290 [ 1148, 4065, 1516, 815, 199], [ 1191, 2489, 2561, 2421, 2443],
291 [ 770, -5915, 5515, -368, -3199], [ 1190, 1047, 3742, 6927, -2089],
292 [ 292, 3099, 4308, -758, -2455], [ 523, 3921, 4044, 1386, 85],
293 [ 4367, 1006, -1252, -1466, -1383], [ 3852, 1579, -77, 2064, 868],
294 [ 5109, 2919, -202, 359, -509], [ 3650, 3206, 2303, 1693, 1296],
295 [ 2905, -3907, 229, -1196, -2332], [ 5977, -3585, 805, 3825, -3138],
296 [ 3746, -606, 53, -269, -3301], [ 606, 2018, -1316, 4064, 398]
297];
298
299const RA288_SPEECH_WINDOW: &[f32] = &[
300 0.576690972, 0.580838025, 0.585013986, 0.589219987, 0.59345597, 0.597723007,
301 0.602020264, 0.606384277, 0.610748291, 0.615142822, 0.619598389, 0.624084473,
302 0.628570557, 0.633117676, 0.637695313, 0.642272949, 0.646911621, 0.651580811,
303 0.656280518, 0.66104126, 0.665802002, 0.670593262, 0.675445557, 0.680328369,
304 0.685241699, 0.690185547, 0.695159912, 0.700164795, 0.705230713, 0.710327148,
305 0.715454102, 0.720611572, 0.725830078, 0.731048584, 0.736328125, 0.741638184,
306 0.747009277, 0.752380371, 0.7578125, 0.763305664, 0.768798828, 0.774353027,
307 0.779937744, 0.785583496, 0.791229248, 0.796936035, 0.802703857, 0.808502197,
308 0.814331055, 0.820220947, 0.826141357, 0.832092285, 0.838104248, 0.844146729,
309 0.850250244, 0.856384277, 0.862548828, 0.868774414, 0.875061035, 0.881378174,
310 0.88772583, 0.894134521, 0.900604248, 0.907104492, 0.913635254, 0.920227051,
311 0.926879883, 0.933563232, 0.940307617, 0.94708252, 0.953918457, 0.96081543,
312 0.96774292, 0.974731445, 0.981781006, 0.988861084, 0.994842529, 0.998565674,
313 0.999969482, 0.99911499, 0.996002197, 0.990600586, 0.982910156, 0.973022461,
314 0.960876465, 0.946533203, 0.930053711, 0.911437988, 0.89074707, 0.868041992,
315 0.843322754, 0.816680908, 0.788208008, 0.757904053, 0.725891113, 0.692199707,
316 0.656921387, 0.620178223, 0.582000732, 0.542480469, 0.501739502, 0.459838867,
317 0.416900635, 0.373016357, 0.328277588, 0.282775879, 0.236663818, 0.189971924,
318 0.142852783, 0.0954284668,0.0477600098
319];
320const RA288_SPEECH_BW_TAB: &[f32] = &[
321 0.98828125, 0.976699829, 0.965254128, 0.953942537, 0.942763507, 0.931715488,
322 0.920796931, 0.910006344, 0.899342179, 0.888803005, 0.878387332, 0.868093729,
323 0.857920766, 0.847867012, 0.837931097, 0.828111589, 0.818407178, 0.808816493,
324 0.799338162, 0.789970934, 0.780713439, 0.771564424, 0.762522638, 0.753586829,
325 0.744755745, 0.736028135, 0.727402806, 0.718878567, 0.710454226, 0.702128589,
326 0.693900526, 0.685768902, 0.677732527, 0.669790328, 0.66194123, 0.654184103
327];
328
329const RA288_GAIN_WINDOW: &[f32] = &[
330 0.505699992, 0.524200022, 0.54339999, 0.563300014, 0.583953857, 0.60534668,
331 0.627502441, 0.650482178, 0.674316406, 0.699005127, 0.724578857, 0.75112915,
332 0.778625488, 0.807128906, 0.836669922, 0.86730957, 0.899078369, 0.932006836,
333 0.961486816, 0.982757568, 0.995635986, 1.0, 0.995819092, 0.983154297,
334 0.96206665, 0.932769775, 0.895507813, 0.850585938, 0.798400879, 0.739379883,
335 0.674072266, 0.602996826, 0.526763916, 0.446014404, 0.361480713, 0.273834229,
336 0.183868408, 0.0923461914
337];
338const RA288_GAIN_BW_TAB: &[f32] = &[
339 0.90625, 0.821289063, 0.74432373, 0.674499512, 0.61126709,
340 0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227
341];