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::*;
7 use super::binkauddata::*;
15 struct BinkAudioDecoder {
23 bands: [usize; MAX_BANDS + 1],
27 delay: [[f32; 256]; 2],
32 fn read_bink_float(br: &mut BitReader) -> DecoderResult<f32> {
33 /*let exp = (br.read(5)? as i8) - 23;
34 let mant = br.read(23)? as u32;
35 let sign = br.read_bool()?;
37 (mant as f32) * ((1 << exp) as f32)
39 (mant as f32) / ((1 << -exp) as f32)
46 let exp = br.read(5)? as u8;
47 let mant = br.read(23)?;
48 let sign = br.read(1)?;
49 let nexp = exp.wrapping_add(0x7E) as u32;
50 let nmant = (mant << 1) & ((1 << 23) - 1);
51 Ok(f32::from_bits((sign << 31) | (nexp << 23) | nmant))
54 fn overlap(a: &[f32], b: &[f32], dst: &mut [f32], len: usize, step: usize) {
56 dst[i] = (a[i] * ((len - i) as f32) + b[i * step] * (i as f32)) / (len as f32);
60 impl BinkAudioDecoder {
61 fn new(use_dct: bool) -> Self {
63 ainfo: NAAudioInfo::new(0, 1, SND_F32P_FORMAT, 0),
64 chmap: NAChannelMap::new(),
66 transform: Transform::None,
69 quants: get_quants_table(),
70 bands: [MAX_BANDS + 1; 26],
74 delay: [[0.0; 256]; 2],
79 fn decode_block(&mut self, br: &mut BitReader) -> DecoderResult<()> {
81 let flt = br.read(32)?;
82 self.coeffs[0] = f32::from_bits(flt) * self.scale;
83 let flt = br.read(32)?;
84 self.coeffs[1] = f32::from_bits(flt) * self.scale;
86 self.coeffs[0] = read_bink_float(br)? * self.scale;
87 self.coeffs[1] = read_bink_float(br)? * self.scale;
89 let mut quants: [f32; MAX_BANDS] = [0.0; MAX_BANDS];
90 for quant in quants[..self.num_bands].iter_mut() {
91 let idx = br.read(8)? as usize;
92 *quant = self.quants[idx.min(self.quants.len() - 1)] * self.scale;
96 self.coeffs = [0.0; 4096];
97 while idx < self.len {
98 let width = if self.version_b {
100 } else if br.read_bool()? {
101 let idx = br.read(4)? as usize;
106 let end = (idx + width).min(self.len);
107 let bits = br.read(4)? as u8;
110 while self.bands[band_idx] <= i { band_idx += 1; }
111 let q = quants[band_idx - 1];
112 let coeff = br.read(bits)?;
115 self.coeffs[i] = -(coeff as f32) * q;
117 self.coeffs[i] = (coeff as f32) * q;
126 #[allow(clippy::identity_op)]
127 #[allow(clippy::transmute_ptr_to_ptr)]
128 fn output(&mut self, dst: &mut [f32], off0: usize, off1: usize, chno: usize) {
129 match self.transform {
130 Transform::DCT(ref mut dct) => {
131 dct.do_dct_inplace(&mut self.coeffs[0..]);
133 Transform::RDFT(ref mut rdft) => {
135 let buf = &mut self.coeffs[0..];
136 rdft.do_rdft_inplace(std::mem::transmute::<&mut [f32], &mut [FFTComplex]>(buf));
138 for i in (0..self.coeffs.len()).step_by(2) {
139 self.coeffs.swap(i, i + 1);
144 if self.use_dct || self.chmap.num_channels() == 1 {
145 let overlap_len = if self.first_frm { 0 } else { self.len >> 4 };
146 let out = if chno == 0 { &mut dst[off0..] } else { &mut dst[off1..] };
147 overlap(&self.delay[chno], &self.coeffs, out, overlap_len, 1);
148 let out2 = &mut out[overlap_len..self.duration];
149 out2.copy_from_slice(&self.coeffs[overlap_len..self.duration]);
150 for i in 0..(self.len >> 4) {
151 self.delay[chno][i] = self.coeffs[self.duration + i];
154 let overlap_len = if self.first_frm { 0 } else { self.len >> 8 };
155 overlap(&self.delay[0], &self.coeffs[0..], &mut dst[off0..], overlap_len, 2);
156 overlap(&self.delay[1], &self.coeffs[1..], &mut dst[off1..], overlap_len, 2);
157 for i in overlap_len..self.duration {
158 dst[i + off0] = self.coeffs[i * 2 + 0];
159 dst[i + off1] = self.coeffs[i * 2 + 1];
161 for i in 0..(self.len >> 8) {
162 self.delay[0][i] = self.coeffs[self.duration * 2 + i * 2 + 0];
163 self.delay[1][i] = self.coeffs[self.duration * 2 + i * 2 + 1];
169 impl NADecoder for BinkAudioDecoder {
170 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
171 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
172 let srate = ainfo.get_sample_rate();
173 let channels = ainfo.get_channels();
174 validate!(channels <= 2);
175 self.ainfo = NAAudioInfo::new(srate, channels, SND_F32P_FORMAT, 2);
176 self.chmap = NAChannelMap::from_str(if channels == 2 {"L,R"} else {"C"}).unwrap();
177 if let Some(ref edata) = info.get_extradata() {
178 if edata.as_slice() == b"BIKb" {
179 self.version_b = true;
182 self.version_b = false;
184 let mut frame_bits = if srate < 22050 { 9 } else if srate < 44100 { 10 } else { 11 };
185 if !self.use_dct && !self.version_b && channels > 1 {
188 self.len = 1 << frame_bits;
189 self.duration = self.len - (self.len >> 4);
190 let single = !self.use_dct && channels == 2; // RDFT codes samples interleaved as single buffer
194 self.transform = if !self.use_dct {
195 Transform::RDFT(RDFTBuilder::new_rdft(self.len >> 1, false, false))
197 Transform::DCT(DCT::new(DCTMode::DCT_III, self.len))
199 self.scale = if !self.use_dct {
200 1.0 / (32768.0 * (self.len as f32).sqrt())
202 (2.0 / (self.len as f32)).sqrt() / 1024.0
204 let s_srate = if single { srate } else { srate >> 1 } as usize;
205 init_bands(s_srate, self.len, &mut self.num_bands, &mut self.bands);
206 self.first_frm = true;
210 Err(DecoderError::InvalidData)
213 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
214 let info = pkt.get_stream().get_info();
215 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
216 let pktbuf = pkt.get_buffer();
217 validate!(pktbuf.len() > 1);
218 let mut br = BitReader::new(&pktbuf, BitReaderMode::LE);
219 let nsamples = br.read(32)? as usize;
220 // validate!(nsamples % self.duration == 0);
222 let abuf = alloc_audio_buffer(self.ainfo, nsamples / self.chmap.num_channels() / 2, self.chmap.clone())?;
223 let mut adata = abuf.get_abuf_f32().unwrap();
224 let mut off0 = adata.get_offset(0);
225 let mut off1 = adata.get_offset(1);
226 let dst = adata.get_data_mut().unwrap();
228 let num_subframes = nsamples / self.duration / self.chmap.num_channels() / 2;
230 for _subfrm in 0..num_subframes {
234 self.decode_block(&mut br)?;
235 self.output(&mut dst[0..], off0, off1, 0);
236 if self.chmap.num_channels() > 1 && self.use_dct {
237 self.decode_block(&mut br)?;
238 self.output(&mut dst[0..], off0, off1, 1);
240 self.first_frm = false;
241 let left = br.left() & 31;
243 br.skip(left as u32)?;
245 off0 += self.duration;
246 off1 += self.duration;
249 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
250 frm.set_duration(Some(self.duration as u64));
251 frm.set_keyframe(false);
254 Err(DecoderError::InvalidData)
257 fn flush(&mut self) {
258 self.delay = [[0.0; 256]; 2];
262 impl NAOptionHandler for BinkAudioDecoder {
263 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
264 fn set_options(&mut self, _options: &[NAOption]) { }
265 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
268 pub fn get_decoder_dct() -> Box<dyn NADecoder + Send> {
269 Box::new(BinkAudioDecoder::new(true))
272 pub fn get_decoder_rdft() -> Box<dyn NADecoder + Send> {
273 Box::new(BinkAudioDecoder::new(false))
278 use nihav_core::codecs::RegisteredDecoders;
279 use nihav_core::demuxers::RegisteredDemuxers;
280 use nihav_codec_support::test::dec_video::*;
281 use crate::rad_register_all_decoders;
282 use crate::rad_register_all_demuxers;
285 fn test_bink_audio_dct() {
286 let mut dmx_reg = RegisteredDemuxers::new();
287 rad_register_all_demuxers(&mut dmx_reg);
288 let mut dec_reg = RegisteredDecoders::new();
289 rad_register_all_decoders(&mut dec_reg);
291 // sample: https://samples.mplayerhq.hu/game-formats/bink/ActivisionLogo.bik
292 let file = "assets/RAD/ActivisionLogo.bik";
293 test_decode_audio("bink", file, None, None/*Some("bink")*/, &dmx_reg, &dec_reg);
296 fn test_bink_audio_rdft_mono() {
297 let mut dmx_reg = RegisteredDemuxers::new();
298 rad_register_all_demuxers(&mut dmx_reg);
299 let mut dec_reg = RegisteredDecoders::new();
300 rad_register_all_decoders(&mut dec_reg);
302 // sample from Star Trek: Armada demo
303 let file = "assets/RAD/F1DEM1.bik";
304 test_decode_audio("bink", file, None, None/*Some("bink")*/, &dmx_reg, &dec_reg);
307 fn test_bink_audio_rdft_stereo() {
308 let mut dmx_reg = RegisteredDemuxers::new();
309 rad_register_all_demuxers(&mut dmx_reg);
310 let mut dec_reg = RegisteredDecoders::new();
311 rad_register_all_decoders(&mut dec_reg);
313 // sample from Heroes of Might and Magic 3
314 let file = "assets/RAD/NWCLOGO.BIK";
315 test_decode_audio("bink", file, None, None/*Some("bink")*/, &dmx_reg, &dec_reg);