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;
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;
20 info: Rc<NACodecInfo>,
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],
30 const BF_ORDER: usize = SP_LPC_ORDER + 1;
31 const BF_WORK_SIZE: usize = SP_LPC_ORDER + 40 + 35;
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();
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];
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);
50 for i in 0..(order + 1) {
51 rec[i] = rec[i] * 0.5625 + tmp1[i];
52 temp[i] = rec[i] + tmp2[i];
54 temp[0] *= 257.0 / 256.0;
56 if compute_lpc(&temp, filt) {
57 for (f, c) in filt.iter_mut().zip(bw_tab.iter()) {
61 for i in 0..move_size {
62 hist[i] = hist[i + start];
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)) {
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) {
81 let mut r = -autoc[i + 1];
83 r -= filt[j] * autoc[i - j];
89 for j in 0..((i + 1) >> 1) {
91 let b = filt[i - j - 1];
93 filt[i - j - 1] = b + r * f;
96 if err < 0.0 { return false; }
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];
113 chmap: NAChannelMap::new(),
114 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, NBLOCKS * BLOCKSIZE),
115 info: NACodecInfo::new_dummy(),
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],
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];
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];
134 sum = sum.max(0.0).min(60.0);
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;
142 let mut sum: f32 = 0.0;
143 for el in buf.iter() {
144 sum += *el * *el * (((1 << 24) as f32) / 5.0);
147 for i in 0..(GAIN_LPC_ORDER - 1) {
148 self.gain_hist[GAIN_START + i] = self.gain_hist[GAIN_START + i + 1];
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);
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(),
161 SND_F32P_FORMAT, NBLOCKS * BLOCKSIZE);
162 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo.clone()));
165 Err(DecoderError::InvalidData)
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;
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();
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);
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;
186 self.process_subblock(gain, cb);
188 for j in 0..BLOCKSIZE {
189 block[j] = self.speech_hist[SP_START + SP_LPC_ORDER + j];
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);
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)))
204 pub fn get_decoder() -> Box<NADecoder> {
205 Box::new(RA288Decoder::new())
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;
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);
222 let file = "assets/RV/A0000044.rm";
223 test_decode_audio("realmedia", file, Some(5000), "ra28.8", &dmx_reg, &dec_reg);
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
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]
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
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
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
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