| 1 | use nihav_core::formats; |
| 2 | use nihav_core::codecs::*; |
| 3 | use nihav_core::io::byteio::*; |
| 4 | use std::str::FromStr; |
| 5 | |
| 6 | |
| 7 | pub fn get_decoder_video() -> Box<NADecoder> { |
| 8 | unimplemented!(); |
| 9 | } |
| 10 | |
| 11 | struct BMV3AudioDecoder { |
| 12 | ainfo: NAAudioInfo, |
| 13 | chmap: NAChannelMap, |
| 14 | pred: [i16; 2], |
| 15 | nframes: usize, |
| 16 | } |
| 17 | |
| 18 | impl BMV3AudioDecoder { |
| 19 | fn new() -> Self { |
| 20 | Self { |
| 21 | ainfo: NAAudioInfo::new(0, 1, formats::SND_S16P_FORMAT, 0), |
| 22 | chmap: NAChannelMap::new(), |
| 23 | pred: [0; 2], |
| 24 | nframes: 0, |
| 25 | } |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | fn decode_block(mode: u8, src: &[u8], dst: &mut [i16], mut pred: i16) -> i16 { |
| 30 | let steps = &BMV_AUDIO_STEPS[mode as usize]; |
| 31 | let mut val2 = 0; |
| 32 | for i in 0..10 { |
| 33 | let val = (src[i * 2 + 0] as usize) + (src[i * 2 + 1] as usize) * 256; |
| 34 | pred = pred.wrapping_add(steps[(val >> 10) & 0x1F]); |
| 35 | dst[i * 3 + 0] = pred; |
| 36 | pred = pred.wrapping_add(steps[(val >> 5) & 0x1F]); |
| 37 | dst[i * 3 + 1] = pred; |
| 38 | pred = pred.wrapping_add(steps[(val >> 0) & 0x1F]); |
| 39 | dst[i * 3 + 2] = pred; |
| 40 | val2 = (val2 << 1) | (val >> 15); |
| 41 | } |
| 42 | pred = pred.wrapping_add(steps[(val2 >> 5) & 0x1F]); |
| 43 | dst[3 * 10 + 0] = pred; |
| 44 | pred = pred.wrapping_add(steps[(val2 >> 0) & 0x1F]); |
| 45 | dst[3 * 10 + 1] = pred; |
| 46 | pred |
| 47 | } |
| 48 | |
| 49 | impl NADecoder for BMV3AudioDecoder { |
| 50 | fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> { |
| 51 | if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { |
| 52 | self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), formats::SND_S16P_FORMAT, 32); |
| 53 | self.chmap = NAChannelMap::from_str("L,R").unwrap(); |
| 54 | Ok(()) |
| 55 | } else { |
| 56 | Err(DecoderError::InvalidData) |
| 57 | } |
| 58 | } |
| 59 | fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { |
| 60 | let info = pkt.get_stream().get_info(); |
| 61 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { |
| 62 | let pktbuf = pkt.get_buffer(); |
| 63 | validate!(pktbuf.len() > 1); |
| 64 | let samples = (pktbuf.len() / 41) * 32; |
| 65 | let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?; |
| 66 | let mut adata = abuf.get_abuf_i16().unwrap(); |
| 67 | let off1 = adata.get_offset(1); |
| 68 | let mut dst = adata.get_data_mut(); |
| 69 | let mut first = pktbuf[0] == 0; |
| 70 | let psrc = &pktbuf[1..]; |
| 71 | for (n, src) in psrc.chunks_exact(41).enumerate() { |
| 72 | let aoff0 = n * 32; |
| 73 | let aoff1 = aoff0 + off1; |
| 74 | if first { |
| 75 | let mode = src[40]; |
| 76 | self.pred[0] = decode_block(mode >> 4, &src[0..], &mut dst[aoff0..], self.pred[0]); |
| 77 | self.pred[1] = decode_block(mode & 0xF, &src[20..], &mut dst[aoff1..], self.pred[1]); |
| 78 | } else { |
| 79 | let mode = src[0]; |
| 80 | self.pred[0] = decode_block(mode >> 4, &src[1..], &mut dst[aoff0..], self.pred[0]); |
| 81 | self.pred[1] = decode_block(mode & 0xF, &src[21..], &mut dst[aoff1..], self.pred[1]); |
| 82 | } |
| 83 | first = !first; |
| 84 | } |
| 85 | self.nframes += 1; |
| 86 | let mut frm = NAFrame::new_from_pkt(pkt, info, abuf); |
| 87 | frm.set_duration(Some(samples as u64)); |
| 88 | frm.set_keyframe(false); |
| 89 | Ok(Rc::new(RefCell::new(frm))) |
| 90 | } else { |
| 91 | Err(DecoderError::InvalidData) |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | pub fn get_decoder_audio() -> Box<NADecoder> { |
| 97 | Box::new(BMV3AudioDecoder::new()) |
| 98 | } |
| 99 | |
| 100 | #[cfg(test)] |
| 101 | mod test { |
| 102 | use nihav_core::codecs::RegisteredDecoders; |
| 103 | use nihav_core::demuxers::RegisteredDemuxers; |
| 104 | use nihav_core::test::dec_video::*; |
| 105 | use crate::codecs::game_register_all_codecs; |
| 106 | use crate::demuxers::game_register_all_demuxers; |
| 107 | #[test] |
| 108 | fn test_bmv_video() { |
| 109 | let mut dmx_reg = RegisteredDemuxers::new(); |
| 110 | game_register_all_demuxers(&mut dmx_reg); |
| 111 | let mut dec_reg = RegisteredDecoders::new(); |
| 112 | game_register_all_codecs(&mut dec_reg); |
| 113 | |
| 114 | let file = "assets/Game/DW3-Loffnote.bmv"; |
| 115 | test_file_decoding("bmv3", file, Some(40), true, false, None, &dmx_reg, &dec_reg); |
| 116 | } |
| 117 | #[test] |
| 118 | fn test_bmv_audio() { |
| 119 | let mut dmx_reg = RegisteredDemuxers::new(); |
| 120 | game_register_all_demuxers(&mut dmx_reg); |
| 121 | let mut dec_reg = RegisteredDecoders::new(); |
| 122 | game_register_all_codecs(&mut dec_reg); |
| 123 | |
| 124 | let file = "assets/Game/DW3-Loffnote.bmv"; |
| 125 | test_decode_audio("bmv3", file, None, "bmv3", &dmx_reg, &dec_reg); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | const BMV_AUDIO_STEPS: [[i16; 32]; 16] = [ |
| 130 | [ |
| 131 | 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, |
| 132 | 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, |
| 133 | -0x4000, -0x3C00, -0x3800, -0x3400, -0x3000, -0x2C00, -0x2800, -0x2400, |
| 134 | -0x2000, -0x1C00, -0x1800, -0x1400, -0x1000, -0x0C00, -0x0800, -0x0400 |
| 135 | ], [ |
| 136 | 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0A00, 0x0C00, 0x0E00, |
| 137 | 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1A00, 0x1C00, 0x1E00, |
| 138 | -0x2000, -0x1E00, -0x1C00, -0x1A00, -0x1800, -0x1600, -0x1400, -0x1200, |
| 139 | -0x1000, -0x0E00, -0x0C00, -0x0A00, -0x0800, -0x0600, -0x0400, -0x0200 |
| 140 | ], [ |
| 141 | 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, |
| 142 | 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, |
| 143 | -0x1000, -0x0F00, -0x0E00, -0x0D00, -0x0C00, -0x0B00, -0x0A00, -0x0900, |
| 144 | -0x0800, -0x0700, -0x0600, -0x0500, -0x0400, -0x0300, -0x0200, -0x0100 |
| 145 | ], [ |
| 146 | 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, |
| 147 | 0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780, |
| 148 | -0x800, -0x780, -0x700, -0x680, -0x600, -0x580, -0x500, -0x480, |
| 149 | -0x400, -0x380, -0x300, -0x280, -0x200, -0x180, -0x100, -0x080 |
| 150 | ], [ |
| 151 | 0x000, 0x048, 0x090, 0x0D8, 0x120, 0x168, 0x1B0, 0x1F8, |
| 152 | 0x240, 0x288, 0x2D0, 0x318, 0x360, 0x3A8, 0x3F0, 0x438, |
| 153 | -0x480, -0x438, -0x3F0, -0x3A8, -0x360, -0x318, -0x2D0, -0x288, |
| 154 | -0x240, -0x1F8, -0x1B0, -0x168, -0x120, -0x0D8, -0x090, -0x048 |
| 155 | ], [ |
| 156 | 0x000, 0x030, 0x060, 0x090, 0x0C0, 0x0F0, 0x120, 0x150, |
| 157 | 0x180, 0x1B0, 0x1E0, 0x210, 0x240, 0x270, 0x2A0, 0x2D0, |
| 158 | -0x300, -0x2D0, -0x2A0, -0x270, -0x240, -0x210, -0x1E0, -0x1B0, |
| 159 | -0x180, -0x150, -0x120, -0x0F0, -0x0C0, -0x090, -0x060, -0x030 |
| 160 | ], [ |
| 161 | 0x000, 0x020, 0x040, 0x060, 0x080, 0x0A0, 0x0C0, 0x0E0, |
| 162 | 0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0, 0x1E0, |
| 163 | -0x200, -0x1E0, -0x1C0, -0x1A0, -0x180, -0x160, -0x140, -0x120, |
| 164 | -0x100, -0x0E0, -0x0C0, -0x0A0, -0x080, -0x060, -0x040, -0x020 |
| 165 | ], [ |
| 166 | 0x000, 0x016, 0x02C, 0x042, 0x058, 0x06E, 0x084, 0x09A, |
| 167 | 0x0B0, 0x0C6, 0x0DC, 0x0F2, 0x108, 0x11E, 0x134, 0x14A, |
| 168 | -0x160, -0x14A, -0x134, -0x11E, -0x108, -0x0F2, -0x0DC, -0x0C6, |
| 169 | -0x0B0, -0x09A, -0x084, -0x06E, -0x058, -0x042, -0x02C, -0x016 |
| 170 | ], [ |
| 171 | 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, |
| 172 | 0x080, 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, |
| 173 | -0x100, -0x0F0, -0x0E0, -0x0D0, -0x0C0, -0x0B0, -0x0A0, -0x090, |
| 174 | -0x080, -0x070, -0x060, -0x050, -0x040, -0x030, -0x020, -0x010 |
| 175 | ], [ |
| 176 | 0x00, 0x0B, 0x16, 0x21, 0x2C, 0x37, 0x42, 0x4D, |
| 177 | 0x58, 0x63, 0x6E, 0x79, 0x84, 0x8F, 0x9A, 0xA5, |
| 178 | -0xB0, -0xA5, -0x9A, -0x8F, -0x84, -0x79, -0x6E, -0x63, |
| 179 | -0x58, -0x4D, -0x42, -0x37, -0x2C, -0x21, -0x16, -0x0B |
| 180 | ], [ |
| 181 | 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, |
| 182 | 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, |
| 183 | -0x80, -0x78, -0x70, -0x68, -0x60, -0x58, -0x50, -0x48, |
| 184 | -0x40, -0x38, -0x30, -0x28, -0x20, -0x18, -0x10, -0x08 |
| 185 | ], [ |
| 186 | 0x00, 0x06, 0x0C, 0x12, 0x18, 0x1E, 0x24, 0x2A, |
| 187 | 0x30, 0x36, 0x3C, 0x42, 0x48, 0x4E, 0x54, 0x5A, |
| 188 | -0x60, -0x5A, -0x54, -0x4E, -0x48, -0x42, -0x3C, -0x36, |
| 189 | -0x30, -0x2A, -0x24, -0x1E, -0x18, -0x12, -0x0C, -0x06 |
| 190 | ], [ |
| 191 | 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, |
| 192 | 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C, |
| 193 | -0x40, -0x3C, -0x38, -0x34, -0x30, -0x2C, -0x28, -0x24, |
| 194 | -0x20, -0x1C, -0x18, -0x14, -0x10, -0x0C, -0x08, -0x04 |
| 195 | ], [ |
| 196 | 0x00, 0x02, 0x05, 0x08, 0x0B, 0x0D, 0x10, 0x13, |
| 197 | 0x16, 0x18, 0x1B, 0x1E, 0x21, 0x23, 0x26, 0x29, |
| 198 | -0x2C, -0x2A, -0x27, -0x24, -0x21, -0x1F, -0x1C, -0x19, |
| 199 | -0x16, -0x14, -0x11, -0x0E, -0x0B, -0x09, -0x06, -0x03 |
| 200 | ], [ |
| 201 | 0x00, 0x01, 0x03, 0x05, 0x07, 0x08, 0x0A, 0x0C, |
| 202 | 0x0E, 0x0F, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, |
| 203 | -0x1C, -0x1B, -0x19, -0x17, -0x15, -0x14, -0x12, -0x10, |
| 204 | -0x0E, -0x0D, -0x0B, -0x09, -0x07, -0x06, -0x04, -0x02 |
| 205 | ], [ |
| 206 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 207 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
| 208 | -0x10, -0x0F, -0x0E, -0x0D, -0x0C, -0x0B, -0x0A, -0x09, |
| 209 | -0x08, -0x07, -0x06, -0x05, -0x04, -0x03, -0x02, -0x01 |
| 210 | ] |
| 211 | ]; |