1 use nihav_core::codecs::*;
2 use nihav_core::dsp::dct::*;
3 use nihav_core::dsp::fft::*;
4 use nihav_core::io::bitreader::*;
14 const MAX_BANDS: usize = 25;
16 struct BinkAudioDecoder {
24 bands: [usize; MAX_BANDS + 1],
28 delay: [[f32; 256]; 2],
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()?;
38 (mant as f32) * ((1 << exp) as f32)
40 (mant as f32) / ((1 << -exp) as f32)
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))
55 fn overlap(a: &[f32], b: &[f32], dst: &mut [f32], len: usize, step: usize) {
57 dst[i] = (a[i] * ((len - i) as f32) + b[i * step] * (i as f32)) / (len as f32);
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();
68 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, 0),
69 chmap: NAChannelMap::new(),
71 transform: Transform::None,
75 bands: [MAX_BANDS + 1; 26],
79 delay: [[0.0; 256]; 2],
84 fn decode_block(&mut self, br: &mut BitReader) -> DecoderResult<()> {
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;
91 self.coeffs[0] = read_bink_float(br)? * self.scale;
92 self.coeffs[1] = read_bink_float(br)? * self.scale;
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;
100 let mut band_idx = 0;
101 self.coeffs = [0.0; 4096];
102 while idx < self.len {
103 let width = if self.version_b {
107 let idx = br.read(4)? as usize;
113 let end = (idx + width).min(self.len);
114 let bits = br.read(4)? as u8;
117 while self.bands[band_idx] <= i { band_idx += 1; }
118 let q = quants[band_idx - 1];
119 let coeff = br.read(bits)?;
122 self.coeffs[i] = -(coeff as f32) * q;
124 self.coeffs[i] = (coeff as f32) * q;
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..]);
138 Transform::RDFT(ref mut rdft) => {
140 let buf = &mut self.coeffs[0..];
141 rdft.do_rdft_inplace(std::mem::transmute::<&mut [f32], &mut [FFTComplex]>(buf));
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];
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];
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];
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,
178 const RUN_TAB: [usize; 16] = [ 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 ];
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;
193 self.version_b = false;
195 let mut frame_bits = if srate < 22050 { 9 } else if srate < 44100 { 10 } else { 11 };
196 if !self.use_dct && !self.version_b {
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
205 self.transform = if !self.use_dct {
206 Transform::RDFT(RDFTBuilder::new_rdft(self.len >> 1, false, false))
208 Transform::DCT(DCT::new(DCTMode::DCT_III, self.len))
210 self.scale = if !self.use_dct {
211 1.0 / (32768.0 * (self.len as f32).sqrt())
213 (2.0 / (self.len as f32)).sqrt() / 1024.0
215 let s_srate = if single { srate } else { srate >> 1 } as usize;
217 while self.num_bands < CRITICAL_FREQS.len() && CRITICAL_FREQS[self.num_bands - 1] < s_srate {
221 for i in 1..self.num_bands {
222 self.bands[i] = (CRITICAL_FREQS[i - 1] * self.len / s_srate) & !1;
224 self.bands[self.num_bands] = self.len;
225 self.first_frm = true;
229 Err(DecoderError::InvalidData)
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);
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();
247 let num_subframes = nsamples / self.duration / self.chmap.num_channels() / 2;
249 for _subfrm in 0..num_subframes {
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);
259 self.first_frm = false;
260 let left = br.left() & 31;
262 br.skip(left as u32)?;
264 off0 += self.duration;
265 off1 += self.duration;
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);
273 Err(DecoderError::InvalidData)
276 fn flush(&mut self) {
277 self.delay = [[0.0; 256]; 2];
281 pub fn get_decoder_dct() -> Box<dyn NADecoder + Send> {
282 Box::new(BinkAudioDecoder::new(true))
285 pub fn get_decoder_rdft() -> Box<dyn NADecoder + Send> {
286 Box::new(BinkAudioDecoder::new(false))
291 use nihav_core::codecs::RegisteredDecoders;
292 use nihav_core::demuxers::RegisteredDemuxers;
293 use nihav_core::test::dec_video::*;
294 use crate::codecs::rad_register_all_codecs;
295 use crate::demuxers::rad_register_all_demuxers;
298 fn test_bink_audio() {
299 let mut dmx_reg = RegisteredDemuxers::new();
300 rad_register_all_demuxers(&mut dmx_reg);
301 let mut dec_reg = RegisteredDecoders::new();
302 rad_register_all_codecs(&mut dec_reg);
304 // let file = "assets/RAD/ActivisionLogo.bik";
305 let file = "assets/RAD/original.bik";
306 // let file = "assets/RAD/Snd0a110c51.dee";
307 // let file = "assets/RAD/NEW.BIK";
308 // let file = "assets/RAD/ge_video_86l.bk2";
309 test_decode_audio("bink", file, None, None/*Some("bink")*/, &dmx_reg, &dec_reg);