1 use nihav_core::formats::*;
2 use nihav_core::frame::*;
3 use nihav_core::codecs::*;
4 use nihav_core::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;
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;
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],
28 const BF_ORDER: usize = SP_LPC_ORDER + 1;
29 const BF_WORK_SIZE: usize = SP_LPC_ORDER + 40 + 35;
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();
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];
41 for i in (0..=order).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);
49 rec[i] = rec[i] * 0.5625 + tmp1[i];
50 temp[i] = rec[i] + tmp2[i];
52 temp[0] *= 257.0 / 256.0;
54 if compute_lpc(&temp, filt) {
55 for (f, c) in filt.iter_mut().zip(bw_tab.iter()) {
59 for i in 0..move_size {
60 hist[i] = hist[i + start];
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)) {
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) {
79 let mut r = -autoc[i + 1];
81 r -= filt[j] * autoc[i - j];
87 for j in 0..((i + 1) >> 1) {
89 let b = filt[i - j - 1];
91 filt[i - j - 1] = b + r * f;
94 if err < 0.0 { return false; }
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];
111 chmap: NAChannelMap::new(),
112 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, NBLOCKS * BLOCKSIZE),
113 info: NACodecInfo::new_dummy(),
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],
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];
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];
132 sum = sum.max(0.0).min(60.0);
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;
140 let mut sum: f32 = 0.0;
141 for el in buf.iter() {
142 sum += *el * *el * (((1 << 24) as f32) / 5.0);
145 for i in 0..(GAIN_LPC_ORDER - 1) {
146 self.gain_hist[GAIN_START + i] = self.gain_hist[GAIN_START + i + 1];
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);
153 impl NADecoder for RA288Decoder {
154 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> 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(),
159 SND_F32P_FORMAT, NBLOCKS * BLOCKSIZE);
160 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
163 Err(DecoderError::InvalidData)
166 fn decode(&mut self, _supp: &mut NADecoderSupport, 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;
173 let abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
174 let mut adata = abuf.get_abuf_f32().unwrap();
175 let dst = adata.get_data_mut().unwrap();
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);
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;
184 self.process_subblock(gain, cb);
186 for j in 0..BLOCKSIZE {
187 block[j] = self.speech_hist[SP_START + SP_LPC_ORDER + j];
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);
196 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
197 frm.set_keyframe(true);
200 fn flush(&mut self) {
204 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
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), None/*Some("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