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