rename register_all_codecs to register_all_decoders
[nihav.git] / nihav-rad / src / codecs / binkaud.rs
1 use nihav_core::codecs::*;
2 use nihav_codec_support::dsp::dct::*;
3 use nihav_codec_support::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,
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 #[allow(clippy::transmute_ptr_to_ptr)]
134 fn output(&mut self, dst: &mut [f32], off0: usize, off1: usize, chno: usize) {
135 match self.transform {
136 Transform::DCT(ref mut dct) => {
137 dct.do_dct_inplace(&mut self.coeffs[0..]);
138 },
139 Transform::RDFT(ref mut rdft) => {
140 unsafe {
141 let buf = &mut self.coeffs[0..];
142 rdft.do_rdft_inplace(std::mem::transmute::<&mut [f32], &mut [FFTComplex]>(buf));
143 }
144 },
145 _ => unreachable!(),
146 };
147 if self.use_dct || self.chmap.num_channels() == 1 {
148 let overlap_len = if self.first_frm { 0 } else { self.len >> 4 };
149 let out = if chno == 0 { &mut dst[off0..] } else { &mut dst[off1..] };
150 overlap(&self.delay[chno], &self.coeffs, out, overlap_len, 1);
151 let out2 = &mut out[overlap_len..self.duration];
152 out2.copy_from_slice(&self.coeffs[overlap_len..self.duration]);
153 for i in 0..(self.len >> 4) {
154 self.delay[chno][i] = self.coeffs[self.duration + i];
155 }
156 } else {
157 let overlap_len = if self.first_frm { 0 } else { self.len >> 8 };
158 overlap(&self.delay[0], &self.coeffs[0..], &mut dst[off0..], overlap_len, 2);
159 overlap(&self.delay[1], &self.coeffs[1..], &mut dst[off1..], overlap_len, 2);
160 for i in overlap_len..self.duration {
161 dst[i + off0] = self.coeffs[i * 2 + 0];
162 dst[i + off1] = self.coeffs[i * 2 + 1];
163 }
164 for i in 0..(self.len >> 8) {
165 self.delay[0][i] = self.coeffs[self.duration * 2 + i * 2 + 0];
166 self.delay[1][i] = self.coeffs[self.duration * 2 + i * 2 + 1];
167 }
168 }
169 }
170 }
171
172 const CRITICAL_FREQS: [usize; MAX_BANDS] = [
173 100, 200, 300, 400, 510, 630, 770, 920,
174 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150,
175 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
176 24500
177 ];
178
179 const RUN_TAB: [usize; 16] = [ 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 ];
180
181 impl NADecoder for BinkAudioDecoder {
182 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
183 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
184 let srate = ainfo.get_sample_rate();
185 let channels = ainfo.get_channels();
186 validate!(channels <= 2);
187 self.ainfo = NAAudioInfo::new(srate, channels, SND_F32P_FORMAT, 2);
188 self.chmap = NAChannelMap::from_str(if channels == 2 {"L,R"} else {"C"}).unwrap();
189 if let Some(ref edata) = info.get_extradata() {
190 if edata.as_slice() == b"BIKb" {
191 self.version_b = true;
192 }
193 } else {
194 self.version_b = false;
195 }
196 let mut frame_bits = if srate < 22050 { 9 } else if srate < 44100 { 10 } else { 11 };
197 if !self.use_dct && !self.version_b {
198 frame_bits += 1;
199 }
200 self.len = 1 << frame_bits;
201 self.duration = self.len - (self.len >> 4);
202 let single = !self.use_dct && channels == 2; // RDFT codes samples interleaved as single buffer
203 if single {
204 self.duration >>= 1;
205 }
206 self.transform = if !self.use_dct {
207 Transform::RDFT(RDFTBuilder::new_rdft(self.len >> 1, false, false))
208 } else {
209 Transform::DCT(DCT::new(DCTMode::DCT_III, self.len))
210 };
211 self.scale = if !self.use_dct {
212 1.0 / (32768.0 * (self.len as f32).sqrt())
213 } else {
214 (2.0 / (self.len as f32)).sqrt() / 1024.0
215 };
216 let s_srate = if single { srate } else { srate >> 1 } as usize;
217 self.num_bands = 1;
218 while self.num_bands < CRITICAL_FREQS.len() && CRITICAL_FREQS[self.num_bands - 1] < s_srate {
219 self.num_bands += 1;
220 }
221 self.bands[0] = 2;
222 for i in 1..self.num_bands {
223 self.bands[i] = (CRITICAL_FREQS[i - 1] * self.len / s_srate) & !1;
224 }
225 self.bands[self.num_bands] = self.len;
226 self.first_frm = true;
227
228 Ok(())
229 } else {
230 Err(DecoderError::InvalidData)
231 }
232 }
233 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
234 let info = pkt.get_stream().get_info();
235 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
236 let pktbuf = pkt.get_buffer();
237 validate!(pktbuf.len() > 1);
238 let mut br = BitReader::new(&pktbuf, BitReaderMode::LE);
239 let nsamples = br.read(32)? as usize;
240 // validate!(nsamples % self.duration == 0);
241
242 let abuf = alloc_audio_buffer(self.ainfo, nsamples / self.chmap.num_channels() / 2, self.chmap.clone())?;
243 let mut adata = abuf.get_abuf_f32().unwrap();
244 let mut off0 = adata.get_offset(0);
245 let mut off1 = adata.get_offset(1);
246 let dst = adata.get_data_mut().unwrap();
247
248 let num_subframes = nsamples / self.duration / self.chmap.num_channels() / 2;
249
250 for _subfrm in 0..num_subframes {
251 if self.use_dct {
252 br.skip(2)?;
253 }
254 self.decode_block(&mut br)?;
255 self.output(&mut dst[0..], off0, off1, 0);
256 if self.chmap.num_channels() > 1 && self.use_dct {
257 self.decode_block(&mut br)?;
258 self.output(&mut dst[0..], off0, off1, 1);
259 }
260 self.first_frm = false;
261 let left = br.left() & 31;
262 if left != 0 {
263 br.skip(left as u32)?;
264 }
265 off0 += self.duration;
266 off1 += self.duration;
267 }
268
269 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
270 frm.set_duration(Some(self.duration as u64));
271 frm.set_keyframe(false);
272 Ok(frm.into_ref())
273 } else {
274 Err(DecoderError::InvalidData)
275 }
276 }
277 fn flush(&mut self) {
278 self.delay = [[0.0; 256]; 2];
279 }
280 }
281
282 impl NAOptionHandler for BinkAudioDecoder {
283 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
284 fn set_options(&mut self, _options: &[NAOption]) { }
285 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
286 }
287
288 pub fn get_decoder_dct() -> Box<dyn NADecoder + Send> {
289 Box::new(BinkAudioDecoder::new(true))
290 }
291
292 pub fn get_decoder_rdft() -> Box<dyn NADecoder + Send> {
293 Box::new(BinkAudioDecoder::new(false))
294 }
295
296 #[cfg(test)]
297 mod test {
298 use nihav_core::codecs::RegisteredDecoders;
299 use nihav_core::demuxers::RegisteredDemuxers;
300 use nihav_codec_support::test::dec_video::*;
301 use crate::rad_register_all_decoders;
302 use crate::rad_register_all_demuxers;
303
304 #[test]
305 fn test_bink_audio_dct() {
306 let mut dmx_reg = RegisteredDemuxers::new();
307 rad_register_all_demuxers(&mut dmx_reg);
308 let mut dec_reg = RegisteredDecoders::new();
309 rad_register_all_decoders(&mut dec_reg);
310
311 let file = "assets/RAD/ActivisionLogo.bik";
312 test_decode_audio("bink", file, None, None/*Some("bink")*/, &dmx_reg, &dec_reg);
313 }
314 #[test]
315 fn test_bink_audio_rdft() {
316 let mut dmx_reg = RegisteredDemuxers::new();
317 rad_register_all_demuxers(&mut dmx_reg);
318 let mut dec_reg = RegisteredDecoders::new();
319 rad_register_all_decoders(&mut dec_reg);
320
321 let file = "assets/RAD/NWCLOGO.BIK";
322 test_decode_audio("bink", file, None, None/*Some("bink")*/, &dmx_reg, &dec_reg);
323 }
324 }