c09bcfb0774a77a2440c378220ac4ac2ba93129e
[nihav.git] / nihav-rad / src / codecs / binkaud.rs
1 use nihav_core::codecs::*;
2 use nihav_core::dsp::dct::*;
3 use nihav_core::dsp::fft::*;
4 use nihav_core::io::bitreader::*;
5 use std::f32::consts;
6 use std::str::FromStr;
7
8 enum Transform {
9 None,
10 DCT(DCT),
11 RDFT(RDFT),
12 }
13
14 const MAX_BANDS: usize = 25;
15
16 struct BinkAudioDecoder {
17 ainfo: NAAudioInfo,
18 chmap: NAChannelMap,
19 use_dct: bool,
20 version_b: bool,
21 transform: Transform,
22 len: usize,
23 quants: [f32; 96],
24 bands: [usize; MAX_BANDS + 1],
25 num_bands: usize,
26 duration: usize,
27 coeffs: [f32; 4096],
28 delay: [[f32; 256]; 2],
29 first_frm: bool,
30 scale: f32,
31 }
32
33 fn read_bink_float(br: &mut BitReader) -> DecoderResult<f32> {
34 /*let exp = (br.read(5)? as i8) - 23;
35 let mant = br.read(23)? as u32;
36 let sign = br.read_bool()?;
37 let v = if exp >= 0 {
38 (mant as f32) * ((1 << exp) as f32)
39 } else {
40 (mant as f32) / ((1 << -exp) as f32)
41 };
42 if sign {
43 Ok(-v)
44 } else {
45 Ok(v)
46 }*/
47 let exp = br.read(5)? as u8;
48 let mant = br.read(23)? as u32;
49 let sign = br.read(1)? as u32;
50 let nexp = exp.wrapping_add(0x7E) as u32;
51 let nmant = (mant << 1) & ((1 << 23) - 1);
52 Ok(f32::from_bits((sign << 31) | (nexp << 23) | nmant))
53 }
54
55 fn overlap(a: &[f32], b: &[f32], dst: &mut [f32], len: usize, step: usize) {
56 for i in 0..len {
57 dst[i] = (a[i] * ((len - i) as f32) + b[i * step] * (i as f32)) / (len as f32);
58 }
59 }
60
61 impl BinkAudioDecoder {
62 fn new(use_dct: bool) -> Self {
63 let mut quants: [f32; 96] = [0.0; 96];
64 for i in 0..quants.len() {
65 quants[i] = ((i as f32) * 0.0664 / consts::LOG10_E).exp();
66 }
67 Self {
68 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, 0),
69 chmap: NAChannelMap::new(),
70 use_dct,
71 transform: Transform::None,
72 version_b: false,
73 len: 0,
74 quants: quants,
75 bands: [MAX_BANDS + 1; 26],
76 num_bands: 0,
77 duration: 0,
78 coeffs: [0.0; 4096],
79 delay: [[0.0; 256]; 2],
80 first_frm: true,
81 scale: 1.0,
82 }
83 }
84 fn decode_block(&mut self, br: &mut BitReader) -> DecoderResult<()> {
85 if self.version_b {
86 let flt = br.read(32)?;
87 self.coeffs[0] = f32::from_bits(flt) * self.scale;
88 let flt = br.read(32)?;
89 self.coeffs[1] = f32::from_bits(flt) * self.scale;
90 } else {
91 self.coeffs[0] = read_bink_float(br)? * self.scale;
92 self.coeffs[1] = read_bink_float(br)? * self.scale;
93 }
94 let mut quants: [f32; MAX_BANDS] = [0.0; MAX_BANDS];
95 for i in 0..self.num_bands {
96 let idx = br.read(8)? as usize;
97 quants[i] = self.quants[idx.min(self.quants.len() - 1)] * self.scale;
98 }
99 let mut idx = 2;
100 let mut band_idx = 0;
101 self.coeffs = [0.0; 4096];
102 while idx < self.len {
103 let width = if self.version_b {
104 16
105 } else {
106 if br.read_bool()? {
107 let idx = br.read(4)? as usize;
108 RUN_TAB[idx] * 8
109 } else {
110 8
111 }
112 };
113 let end = (idx + width).min(self.len);
114 let bits = br.read(4)? as u8;
115 if bits != 0 {
116 for i in idx..end {
117 while self.bands[band_idx] <= i { band_idx += 1; }
118 let q = quants[band_idx - 1];
119 let coeff = br.read(bits)?;
120 if coeff != 0 {
121 if br.read_bool()? {
122 self.coeffs[i] = -(coeff as f32) * q;
123 } else {
124 self.coeffs[i] = (coeff as f32) * q;
125 }
126 }
127 }
128 }
129 idx = end;
130 }
131 Ok(())
132 }
133 fn output(&mut self, dst: &mut [f32], off0: usize, off1: usize, chno: usize) {
134 match self.transform {
135 Transform::DCT(ref mut dct) => {
136 dct.do_dct_inplace(&mut self.coeffs[0..]);
137 },
138 Transform::RDFT(ref mut rdft) => {
139 unsafe {
140 let buf = &mut self.coeffs[0..];
141 rdft.do_rdft_inplace(std::mem::transmute::<&mut [f32], &mut [FFTComplex]>(buf));
142 }
143 },
144 _ => unreachable!(),
145 };
146 if self.use_dct || self.chmap.num_channels() == 1 {
147 let overlap_len = if self.first_frm { 0 } else { self.len >> 4 };
148 let out = if chno == 0 { &mut dst[off0..] } else { &mut dst[off1..] };
149 overlap(&self.delay[chno], &self.coeffs, out, overlap_len, 1);
150 let out2 = &mut out[overlap_len..self.duration];
151 out2.copy_from_slice(&self.coeffs[overlap_len..self.duration]);
152 for i in 0..(self.len >> 4) {
153 self.delay[chno][i] = self.coeffs[self.duration + i];
154 }
155 } else {
156 let overlap_len = if self.first_frm { 0 } else { self.len >> 8 };
157 overlap(&self.delay[0], &self.coeffs[0..], &mut dst[off0..], overlap_len, 2);
158 overlap(&self.delay[1], &self.coeffs[1..], &mut dst[off1..], overlap_len, 2);
159 for i in overlap_len..self.duration {
160 dst[i + off0] = self.coeffs[i * 2 + 0];
161 dst[i + off1] = self.coeffs[i * 2 + 1];
162 }
163 for i in 0..(self.len >> 8) {
164 self.delay[0][i] = self.coeffs[self.duration * 2 + i * 2 + 0];
165 self.delay[1][i] = self.coeffs[self.duration * 2 + i * 2 + 1];
166 }
167 }
168 }
169 }
170
171 const CRITICAL_FREQS: [usize; MAX_BANDS] = [
172 100, 200, 300, 400, 510, 630, 770, 920,
173 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150,
174 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
175 24500
176 ];
177
178 const RUN_TAB: [usize; 16] = [ 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 ];
179
180 impl NADecoder for BinkAudioDecoder {
181 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
182 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
183 let srate = ainfo.get_sample_rate();
184 let channels = ainfo.get_channels();
185 validate!(channels <= 2);
186 self.ainfo = NAAudioInfo::new(srate, channels, SND_F32P_FORMAT, 2);
187 self.chmap = NAChannelMap::from_str(if channels == 2 {"L,R"} else {"C"}).unwrap();
188 if let Some(ref edata) = info.get_extradata() {
189 if edata.as_slice() == b"BIKb" {
190 self.version_b = true;
191 }
192 } else {
193 self.version_b = false;
194 }
195 let mut frame_bits = if srate < 22050 { 9 } else if srate < 44100 { 10 } else { 11 };
196 if !self.use_dct && !self.version_b {
197 frame_bits += 1;
198 }
199 self.len = 1 << frame_bits;
200 self.duration = self.len - (self.len >> 4);
201 let single = !self.use_dct && channels == 2; // RDFT codes samples interleaved as single buffer
202 if single {
203 self.duration >>= 1;
204 }
205 self.transform = if !self.use_dct {
206 Transform::RDFT(RDFTBuilder::new_rdft(FFTMode::SplitRadix, self.len >> 1, false, false))
207 } else {
208 Transform::DCT(DCT::new(DCTMode::DCT_III, self.len))
209 };
210 self.scale = if !self.use_dct {
211 1.0 / (32768.0 * (self.len as f32).sqrt())
212 } else {
213 (2.0 / (self.len as f32)).sqrt() / 1024.0
214 };
215 let s_srate = if single { srate } else { srate >> 1 } as usize;
216 self.num_bands = 1;
217 while self.num_bands < CRITICAL_FREQS.len() && CRITICAL_FREQS[self.num_bands - 1] < s_srate {
218 self.num_bands += 1;
219 }
220 self.bands[0] = 2;
221 for i in 1..self.num_bands {
222 self.bands[i] = (CRITICAL_FREQS[i - 1] * self.len / s_srate) & !1;
223 }
224 self.bands[self.num_bands] = self.len;
225 self.first_frm = true;
226
227 Ok(())
228 } else {
229 Err(DecoderError::InvalidData)
230 }
231 }
232 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
233 let info = pkt.get_stream().get_info();
234 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
235 let pktbuf = pkt.get_buffer();
236 validate!(pktbuf.len() > 1);
237 let mut br = BitReader::new(&pktbuf, pktbuf.len(), BitReaderMode::LE);
238 let nsamples = br.read(32)? as usize;
239 // validate!(nsamples % self.duration == 0);
240
241 let abuf = alloc_audio_buffer(self.ainfo, nsamples / self.chmap.num_channels() / 2, self.chmap.clone())?;
242 let mut adata = abuf.get_abuf_f32().unwrap();
243 let mut off0 = adata.get_offset(0);
244 let mut off1 = adata.get_offset(1);
245 let dst = adata.get_data_mut().unwrap();
246
247 let num_subframes = nsamples / self.duration / self.chmap.num_channels() / 2;
248
249 for _subfrm in 0..num_subframes {
250 if self.use_dct {
251 br.skip(2)?;
252 }
253 self.decode_block(&mut br)?;
254 self.output(&mut dst[0..], off0, off1, 0);
255 if self.chmap.num_channels() > 1 && self.use_dct {
256 self.decode_block(&mut br)?;
257 self.output(&mut dst[0..], off0, off1, 1);
258 }
259 self.first_frm = false;
260 let left = br.left() & 31;
261 if left != 0 {
262 br.skip(left as u32)?;
263 }
264 off0 += self.duration;
265 off1 += self.duration;
266 }
267
268 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
269 frm.set_duration(Some(self.duration as u64));
270 frm.set_keyframe(false);
271 Ok(frm.into_ref())
272 } else {
273 Err(DecoderError::InvalidData)
274 }
275 }
276 }
277
278 pub fn get_decoder_dct() -> Box<NADecoder> {
279 Box::new(BinkAudioDecoder::new(true))
280 }
281
282 pub fn get_decoder_rdft() -> Box<NADecoder> {
283 Box::new(BinkAudioDecoder::new(false))
284 }
285
286 #[cfg(test)]
287 mod test {
288 use nihav_core::codecs::RegisteredDecoders;
289 use nihav_core::demuxers::RegisteredDemuxers;
290 use nihav_core::test::dec_video::*;
291 use crate::codecs::rad_register_all_codecs;
292 use crate::demuxers::rad_register_all_demuxers;
293
294 #[test]
295 fn test_bink_audio() {
296 let mut dmx_reg = RegisteredDemuxers::new();
297 rad_register_all_demuxers(&mut dmx_reg);
298 let mut dec_reg = RegisteredDecoders::new();
299 rad_register_all_codecs(&mut dec_reg);
300
301 // let file = "assets/RAD/ActivisionLogo.bik";
302 let file = "assets/RAD/original.bik";
303 // let file = "assets/RAD/Snd0a110c51.dee";
304 // let file = "assets/RAD/NEW.BIK";
305 // let file = "assets/RAD/ge_video_86l.bk2";
306 test_decode_audio("bink", file, None, "bink", &dmx_reg, &dec_reg);
307 }
308 }