8538f8560b6fec2da1810ccf897a8f6071148f4e
[nihav.git] / nihav-realmedia / src / codecs / ra288.rs
1 use std::rc::Rc;
2 use std::cell::RefCell;
3 use nihav_core::formats::*;
4 use nihav_core::frame::*;
5 use nihav_core::codecs::*;
6 use nihav_core::io::bitreader::*;
7 const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C];
8 const NBLOCKS: usize = 32;
9 const BLOCKSIZE: usize = 5;
10 const FRAME_SIZE: usize = 38;
11
12 const SP_LPC_ORDER: usize = 36;
13 const SP_START: usize = 70;
14 const GAIN_LPC_ORDER: usize = 10;
15 const GAIN_START: usize = 28;
16
17 struct 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
30 const BF_ORDER: usize = SP_LPC_ORDER + 1;
31 const BF_WORK_SIZE: usize = SP_LPC_ORDER + 40 + 35;
32
33 fn 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
66 fn 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
74 fn 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
101 fn 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
110 impl 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
155 impl 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 abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
176 let mut adata = abuf.get_abuf_f32().unwrap();
177 let dst = adata.get_data_mut().unwrap();
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
204 pub fn get_decoder() -> Box<NADecoder> {
205 Box::new(RA288Decoder::new())
206 }
207
208 #[cfg(test)]
209 mod test {
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;
215 #[test]
216 fn test_ra288() {
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
222 let file = "assets/RV/A0000044.rm";
223 test_decode_audio("realmedia", file, Some(5000), "ra28.8", &dmx_reg, &dec_reg);
224 }
225 }
226
227 const 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
232 const 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
299 const 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 ];
320 const 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
329 const 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 ];
338 const 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 ];