]> git.nihav.org Git - nihav.git/blame_incremental - nihav-game/src/codecs/bmv3.rs
codecs: implement Default trait for MV
[nihav.git] / nihav-game / src / codecs / bmv3.rs
... / ...
CommitLineData
1use nihav_core::formats;
2use nihav_core::codecs::*;
3use nihav_core::io::byteio::*;
4use std::str::FromStr;
5
6const BMV_INTRA: u8 = 0x03;
7const BMV_SCROLL: u8 = 0x04;
8const BMV_PAL: u8 = 0x08;
9const BMV_COMMAND: u8 = 0x10;
10const BMV_PRINT: u8 = 0x80;
11
12const BMV_MAX_WIDTH: usize = 640;
13const BMV_MAX_HEIGHT: usize = 432;
14const BMV_MAX_SIZE: usize = BMV_MAX_WIDTH * (BMV_MAX_HEIGHT + 1);
15
16enum BMV3Mode {
17 Normal,
18 Copy,
19 Pixfunc,
20 After0,
21 After1,
22 After1C,
23 After4,
24 After5,
25}
26
27struct NibbleReader {
28 nib: u8,
29 has_nib: bool,
30}
31
32impl NibbleReader {
33 fn new() -> Self {
34 Self { nib: 0, has_nib: false }
35 }
36 fn get_nib(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
37 if self.has_nib {
38 self.has_nib = false;
39 Ok(self.nib)
40 } else {
41 let b = br.read_byte()?;
42 self.nib = b >> 4;
43 self.has_nib = true;
44 Ok(b & 0xF)
45 }
46 }
47 fn get_length(&mut self, br: &mut ByteReader, mut len: usize, mut shift: u8) -> DecoderResult<usize> {
48 loop {
49 let nib = self.get_nib(br)? as usize;
50 len |= nib << shift;
51 shift += 2;
52 if (nib & 0xC) != 0 {
53 return Ok(len - 1);
54 }
55 }
56 }
57 fn push(&mut self, val: u8) {
58 if self.has_nib {
59 panic!("nibble already in cache");
60 } else {
61 self.nib = val;
62 self.has_nib = true;
63 }
64 }
65 fn reset(&mut self) {
66 self.nib = 0;
67 self.has_nib = false;
68 }
69}
70
71struct BMV3VideoDecoder {
72 info: NACodecInfoRef,
73 stride: usize,
74 height: usize,
75 frame: Vec<u16>,
76 prev_frame: Vec<u16>,
77 pixels: [u16; 256],
78 pixbuf: [[u16; 256]; 7],
79 mode: BMV3Mode,
80 pos: usize,
81 end: usize,
82 nr: NibbleReader,
83 is_intra: bool,
84}
85
86impl BMV3VideoDecoder {
87 fn new() -> Self {
88 let mut frame1 = Vec::with_capacity(BMV_MAX_SIZE);
89 frame1.resize(BMV_MAX_SIZE, 0);
90 let mut frame2 = Vec::with_capacity(BMV_MAX_SIZE);
91 frame2.resize(BMV_MAX_SIZE, 0);
92
93 let mut pixels = [0u16; 256];
94 for (i, el) in pixels.iter_mut().enumerate() {
95 *el = i as u16;
96 }
97 let mut pixbuf = [[0u16; 256]; 7];
98 for i in 0..7 {
99 for j in 0..256 {
100 pixbuf[i][j] = ((i << 8) + j + 0xF8) as u16;
101 }
102 }
103
104 Self {
105 info: NACodecInfoRef::default(),
106 stride: 0,
107 height: 0,
108 frame: frame1,
109 prev_frame: frame2,
110 pixels, pixbuf,
111 mode: BMV3Mode::Normal,
112 pos: 0,
113 end: 0,
114 nr: NibbleReader::new(),
115 is_intra: false,
116 }
117 }
118 fn decode_frame(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
119 let mut idx = 0;
120 loop {
121 let op = br.read_byte()?;
122 let mut len;
123 let skip;
124 if op < 0x90 {
125 let op2 = br.read_u16le()?;
126 skip = ((op2 >> 12) as usize) | ((op as usize) << 4);
127 len = (op2 & 0xFFF) as usize;
128 } else {
129 len = ((op & 7) + 1) as usize;
130 skip = ((op >> 3) - 0x11) as usize;
131 }
132 while (idx < 0xF8) && (len > 0) {
133 self.pixels[idx] = br.read_u16le()?;
134 idx += 1;
135 len -= 1;
136 }
137 while (idx < 0x7F8) && (len > 0) {
138 let nidx = idx - 0xF8;
139 self.pixbuf[nidx >> 8][nidx & 0xFF] = br.read_u16le()?;
140 idx += 1;
141 len -= 1;
142 }
143 validate!(len == 0);
144 if skip == 0 { break; }
145 idx += skip;
146 }
147 self.nr.reset();
148 self.mode = BMV3Mode::Normal;
149 while br.left() > 0 && self.pos < self.end {
150 match self.mode {
151 BMV3Mode::Normal => {
152 let op = br.read_byte()?;
153 self.decode_normal(br, op)?;
154 },
155 BMV3Mode::Copy => {
156 let op = br.read_byte()?;
157 if (op & 1) == 0 {
158 self.decode_normal(br, op + 1)?;
159 } else {
160 self.decode_copy(br, op)?;
161 }
162 },
163 BMV3Mode::Pixfunc => {
164 let op = br.read_byte()?;
165 if (op & 1) == 0 {
166 self.decode_copy(br, op + 1)?;
167 } else {
168 self.decode_normal(br, op - 1)?;
169 }
170 },
171 BMV3Mode::After0 => {
172 let cur_op = self.nr.get_nib(br)?;
173 if cur_op < 4 {
174 let op = self.nr.get_nib(br)?;
175 match cur_op {
176 0 => self.decode_mode5c(br, op | 0x10)?,
177 1 => self.decode_mode4 (br, op | 0x10)?,
178 2 => self.decode_mode5c(br, op | 0x30)?,
179 _ => self.decode_mode4 (br, op | 0x30)?,
180 };
181 } else {
182 let len = (cur_op >> 1) - 1;
183 if (cur_op & 1) == 0 {
184 self.pixfunc(br, len as usize)?;
185 } else {
186 self.repeat(len as usize)?;
187 }
188 }
189 }
190 BMV3Mode::After1 => {
191 let cur_op = self.nr.get_nib(br)?;
192 if cur_op < 4 {
193 let op = self.nr.get_nib(br)?;
194 match cur_op {
195 0 => self.decode_mode4 (br, op | 0x10)?,
196 1 => self.decode_mode5c(br, op | 0x00)?,
197 2 => self.decode_mode4 (br, op | 0x30)?,
198 _ => self.decode_mode5c(br, op | 0x20)?,
199 };
200 } else {
201 let len = (cur_op >> 1) - 1;
202 if (cur_op & 1) == 0 {
203 self.repeat(len as usize)?;
204 } else {
205 self.copy(len as usize)?;
206 }
207 }
208 },
209 BMV3Mode::After1C => {
210 let cur_op = self.nr.get_nib(br)?;
211 if cur_op < 4 {
212 let cur_op1 = self.nr.get_nib(br)?;
213 let m5_op = cur_op1 | (cur_op << 4);
214 self.decode_mode5c(br, m5_op)?;
215 } else if (cur_op & 1) == 0 {
216 let len = (cur_op >> 1) - 1;
217 self.copy(len as usize)?;
218 } else {
219 let len = (cur_op >> 1) - 1;
220 self.pixfunc(br, len as usize)?;
221 }
222 },
223 BMV3Mode::After4 => {
224 let cur_op0 = self.nr.get_nib(br)?;
225 let cur_op1 = self.nr.get_nib(br)?;
226 let cur_op = (cur_op0 << 4) | cur_op1;
227 if (cur_op & 0x10) == 0 {
228 self.decode_mode5c(br, cur_op | 0x10)?;
229 } else {
230 self.decode_mode4(br, cur_op)?;
231 }
232 },
233 BMV3Mode::After5 => {
234 let cur_op0 = self.nr.get_nib(br)?;
235 let cur_op1 = self.nr.get_nib(br)?;
236 let cur_op = (cur_op0 << 4) | cur_op1;
237 if (cur_op & 0x10) == 0 {
238 self.decode_mode4(br, cur_op | 0x10)?;
239 } else {
240 self.decode_mode5c(br, cur_op ^ 0x10)?;
241 }
242 },
243 };
244 if self.pos >= self.end { break; }
245 }
246 Ok(())
247 }
248
249 fn copy(&mut self, len: usize) -> DecoderResult<()> {
250 validate!(len <= self.end - self.pos);
251 if self.is_intra {
252 for _ in 0..len {
253 self.frame[self.pos] = self.frame[self.pos - self.stride];
254 self.pos += 1;
255 }
256 } else {
257 for _ in 0..len {
258 self.frame[self.pos] = self.prev_frame[self.pos];
259 self.pos += 1;
260 }
261 }
262 self.mode = BMV3Mode::Copy;
263 Ok(())
264 }
265 fn pixfunc(&mut self, br: &mut ByteReader, len: usize) -> DecoderResult<()> {
266 validate!(len <= self.end - self.pos);
267 for _ in 0..len {
268 let op = BMV_PIXFUNCS_MAP[br.read_byte()? as usize];
269 let val;
270 if op == 0xFF {
271 val = br.read_u16le()?;
272 } else if op >= 0xF8 {
273 let tab_idx = (op - 0xF8) as usize;
274 let sub_idx = br.read_byte()? as usize;
275 val = self.pixbuf[tab_idx][sub_idx];
276 } else {
277 val = self.pixels[op as usize];
278 }
279 self.frame[self.pos] = val;
280 self.pos += 1;
281 }
282 self.mode = BMV3Mode::Pixfunc;
283 Ok(())
284 }
285 fn repeat(&mut self, len: usize) -> DecoderResult<()> {
286 validate!(self.pos > 0);
287 validate!(len <= self.end - self.pos);
288 let pix = self.frame[self.pos - 1];
289 for _ in 0..len {
290 self.frame[self.pos] = pix;
291 self.pos += 1;
292 }
293 self.mode = BMV3Mode::Normal;
294 Ok(())
295 }
296
297 fn decode_normal(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
298 if op < 0x40 {
299 let mode = op & 1;
300 let len = ((op >> 1) & 0x7) as usize;
301 if len < 2 {
302 let mut len = (op >> 3) as usize;
303 if (op & 0xF) >= 2 {
304 len += 1;
305 }
306 len = self.nr.get_length(br, len, 3)?;
307 if (op & 1) == 0 {
308 self.copy(len)?;
309 if self.nr.has_nib {
310 self.mode = BMV3Mode::After0;
311 }
312 } else {
313 self.pixfunc(br, len)?;
314 if self.nr.has_nib {
315 self.mode = BMV3Mode::After1;
316 }
317 }
318 } else if mode == 0 {
319 self.copy(len - 1)?;
320 self.nr.push(op >> 4);
321 self.mode = BMV3Mode::After4;
322 } else {
323 self.pixfunc(br, len - 1)?;
324 self.nr.push(op >> 4);
325 self.mode = BMV3Mode::After5;
326 }
327 return Ok(());
328 }
329 let x_op = (op >> 4) as usize;
330 let y_op = ((op >> 1) & 7) as usize;
331 let flag = (op & 1) as usize;
332 if y_op == 0 || y_op == 1 {
333 let len = x_op * 2 - 1 + y_op;
334 if flag == 0 {
335 self.copy(len)?;
336 } else {
337 self.pixfunc(br, len)?;
338 }
339 } else {
340 let len1 = y_op - 1;
341 let len2 = (x_op >> 1) - 1;
342 if flag == 0 {
343 self.copy(len1)?;
344 } else {
345 self.pixfunc(br, len1)?;
346 }
347 match (x_op & 1) * 2 + flag {
348 0 => self.pixfunc(br, len2)?,
349 1 => self.repeat(len2)?,
350 2 => self.repeat(len2)?,
351 _ => self.copy(len2)?,
352 };
353 }
354 Ok(())
355 }
356 fn decode_copy(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
357 if op < 0x40 {
358 let len = ((op >> 1) & 0x7) as usize;
359 if len < 2 {
360 let mut len = (op >> 3) as usize;
361 if (op & 0xF) >= 2 {
362 len += 1;
363 }
364 len = self.nr.get_length(br, len, 3)?;
365 self.repeat(len)?;
366 if self.nr.has_nib {
367 self.mode = BMV3Mode::After1C;
368 }
369 } else {
370 self.repeat(len - 1)?;
371 if br.left() == 0 { return Ok(()); }
372 let op2 = self.nr.get_nib(br)?;
373 let cur_op = (op & 0xF0) | op2;
374 self.decode_mode5c(br, cur_op)?;
375 }
376 return Ok(());
377 }
378 let x_op = (op >> 4) as usize;
379 let y_op = ((op >> 1) & 7) as usize;
380 if y_op == 0 || y_op == 1 {
381 self.repeat(x_op * 2 - 1 + y_op)?;
382 } else {
383 self.repeat(y_op - 1)?;
384 let len = (x_op >> 1) - 1;
385 if (x_op & 1) == 0 {
386 self.copy(len)?;
387 } else {
388 self.pixfunc(br, len)?;
389 }
390 }
391 Ok(())
392 }
393 fn decode_mode4(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
394 if (op & 0xF) < 4 {
395 let mut len = ((op & 3) * 2) as usize;
396 if (op & 0xF0) >= 0x20 {
397 len += 1;
398 }
399 len = self.nr.get_length(br, len, 3)?;
400 self.repeat(len)?;
401 if self.nr.has_nib {
402 self.mode = BMV3Mode::After1C;
403 }
404 } else {
405 let len = ((op & 0xF) * 2 - 1 + (op >> 5)) as usize;
406 self.repeat(len)?;
407 self.mode = BMV3Mode::After1C;
408 }
409 Ok(())
410 }
411 fn decode_mode5c(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
412 if (op & 0xF) < 4 {
413 let mut len = ((op & 3) * 2) as usize;
414 if (op & 0xF0) >= 0x20 {
415 len += 1;
416 }
417 len = self.nr.get_length(br, len, 3)?;
418 if (op & 0x10) == 0 {
419 self.copy(len)?;
420 if self.nr.has_nib {
421 self.mode = BMV3Mode::After0;
422 }
423 } else {
424 self.pixfunc(br, len)?;
425 if self.nr.has_nib {
426 self.mode = BMV3Mode::After1;
427 }
428 }
429 } else {
430 let len = ((op & 0xF) * 2 - 1 + (op >> 5)) as usize;
431 if (op & 0x10) == 0 {
432 self.copy(len)?;
433 self.mode = BMV3Mode::After0;
434 } else {
435 self.pixfunc(br, len)?;
436 self.mode = BMV3Mode::After1;
437 }
438 }
439 Ok(())
440 }
441}
442
443impl NADecoder for BMV3VideoDecoder {
444 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
445 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
446 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, RGB565_FORMAT));
447 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
448
449 self.stride = vinfo.get_width();
450 self.height = vinfo.get_height();
451 self.end = self.stride * (self.height + 1);
452
453 validate!((self.stride <= 640) && (self.height <= 432));
454
455 Ok(())
456 } else {
457 Err(DecoderError::InvalidData)
458 }
459 }
460 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
461 let src = pkt.get_buffer();
462 validate!(src.len() > 1);
463
464 let mut mr = MemoryReader::new_read(&src);
465 let mut br = ByteReader::new(&mut mr);
466 let flags = br.read_byte()?;
467
468 if (flags & BMV_COMMAND) != 0 {
469 let size = if (flags & BMV_PRINT) != 0 { 8 } else { 10 };
470 br.read_skip(size)?;
471 }
472 if (flags & BMV_PAL) != 0 {
473 return Err(DecoderError::InvalidData);
474 }
475 let off;
476 if ((flags & 1) == 0) && ((flags & BMV_SCROLL) != 0) {
477 off = br.read_u16le()? as usize;
478 } else {
479 off = 0;
480 }
481 self.pos = off + self.stride;
482 self.is_intra = (flags & BMV_INTRA) == BMV_INTRA;
483
484 let bufret = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 0);
485 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
486 let bufinfo = bufret.unwrap();
487
488 self.decode_frame(&mut br)?;
489
490 {
491 let mut buf = bufinfo.get_vbuf16().unwrap();
492 let stride = buf.get_stride(0);
493 let data = buf.get_data_mut().unwrap();
494 let dst = data.as_mut_slice();
495
496 let refbuf = &self.frame[self.stride..];
497 for (dst, src) in dst.chunks_mut(stride).zip(refbuf.chunks(self.stride)).take(self.height) {
498 let out = &mut dst[0..self.stride];
499 out.copy_from_slice(src);
500 }
501 }
502 std::mem::swap(&mut self.frame, &mut self.prev_frame);
503
504 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
505 frm.set_keyframe(self.is_intra);
506 frm.set_frame_type(if self.is_intra { FrameType::I } else { FrameType::P });
507 Ok(frm.into_ref())
508 }
509}
510
511
512pub fn get_decoder_video() -> Box<NADecoder> {
513 Box::new(BMV3VideoDecoder::new())
514}
515
516struct BMV3AudioDecoder {
517 ainfo: NAAudioInfo,
518 chmap: NAChannelMap,
519 pred: [i16; 2],
520 nframes: usize,
521}
522
523impl BMV3AudioDecoder {
524 fn new() -> Self {
525 Self {
526 ainfo: NAAudioInfo::new(0, 1, formats::SND_S16P_FORMAT, 0),
527 chmap: NAChannelMap::new(),
528 pred: [0; 2],
529 nframes: 0,
530 }
531 }
532}
533
534fn decode_block(mode: u8, src: &[u8], dst: &mut [i16], mut pred: i16) -> i16 {
535 let steps = &BMV_AUDIO_STEPS[mode as usize];
536 let mut val2 = 0;
537 for i in 0..10 {
538 let val = (src[i * 2 + 0] as usize) + (src[i * 2 + 1] as usize) * 256;
539 pred = pred.wrapping_add(steps[(val >> 10) & 0x1F]);
540 dst[i * 3 + 0] = pred;
541 pred = pred.wrapping_add(steps[(val >> 5) & 0x1F]);
542 dst[i * 3 + 1] = pred;
543 pred = pred.wrapping_add(steps[(val >> 0) & 0x1F]);
544 dst[i * 3 + 2] = pred;
545 val2 = (val2 << 1) | (val >> 15);
546 }
547 pred = pred.wrapping_add(steps[(val2 >> 5) & 0x1F]);
548 dst[3 * 10 + 0] = pred;
549 pred = pred.wrapping_add(steps[(val2 >> 0) & 0x1F]);
550 dst[3 * 10 + 1] = pred;
551 pred
552}
553
554impl NADecoder for BMV3AudioDecoder {
555 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
556 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
557 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), formats::SND_S16P_FORMAT, 32);
558 self.chmap = NAChannelMap::from_str("L,R").unwrap();
559 Ok(())
560 } else {
561 Err(DecoderError::InvalidData)
562 }
563 }
564 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
565 let info = pkt.get_stream().get_info();
566 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
567 let pktbuf = pkt.get_buffer();
568 validate!(pktbuf.len() > 1);
569 let samples = (pktbuf.len() / 41) * 32;
570 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
571 let mut adata = abuf.get_abuf_i16().unwrap();
572 let off1 = adata.get_offset(1);
573 let dst = adata.get_data_mut().unwrap();
574 let mut first = pktbuf[0] == 0;
575 let psrc = &pktbuf[1..];
576 for (n, src) in psrc.chunks_exact(41).enumerate() {
577 let aoff0 = n * 32;
578 let aoff1 = aoff0 + off1;
579 if first {
580 let mode = src[40];
581 self.pred[0] = decode_block(mode >> 4, &src[0..], &mut dst[aoff0..], self.pred[0]);
582 self.pred[1] = decode_block(mode & 0xF, &src[20..], &mut dst[aoff1..], self.pred[1]);
583 } else {
584 let mode = src[0];
585 self.pred[0] = decode_block(mode >> 4, &src[1..], &mut dst[aoff0..], self.pred[0]);
586 self.pred[1] = decode_block(mode & 0xF, &src[21..], &mut dst[aoff1..], self.pred[1]);
587 }
588 first = !first;
589 }
590 self.nframes += 1;
591 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
592 frm.set_duration(Some(samples as u64));
593 frm.set_keyframe(false);
594 Ok(frm.into_ref())
595 } else {
596 Err(DecoderError::InvalidData)
597 }
598 }
599}
600
601pub fn get_decoder_audio() -> Box<NADecoder> {
602 Box::new(BMV3AudioDecoder::new())
603}
604
605#[cfg(test)]
606mod test {
607 use nihav_core::codecs::RegisteredDecoders;
608 use nihav_core::demuxers::RegisteredDemuxers;
609 use nihav_core::test::dec_video::*;
610 use crate::codecs::game_register_all_codecs;
611 use crate::demuxers::game_register_all_demuxers;
612 #[test]
613 fn test_bmv_video() {
614 let mut dmx_reg = RegisteredDemuxers::new();
615 game_register_all_demuxers(&mut dmx_reg);
616 let mut dec_reg = RegisteredDecoders::new();
617 game_register_all_codecs(&mut dec_reg);
618
619 let file = "assets/Game/DW3-Loffnote.bmv";
620 test_file_decoding("bmv3", file, None, true, false, None, &dmx_reg, &dec_reg);
621 }
622 #[test]
623 fn test_bmv_audio() {
624 let mut dmx_reg = RegisteredDemuxers::new();
625 game_register_all_demuxers(&mut dmx_reg);
626 let mut dec_reg = RegisteredDecoders::new();
627 game_register_all_codecs(&mut dec_reg);
628
629 let file = "assets/Game/DW3-Loffnote.bmv";
630 test_decode_audio("bmv3", file, None, "bmv3", &dmx_reg, &dec_reg);
631 }
632}
633
634const BMV_PIXFUNCS_MAP: [u8; 256] = [
635 0x38, 0x78, 0xB8, 0xF9,
636 0x39, 0x79, 0xB9, 0xFA,
637 0x3A, 0x7A, 0xBA, 0xFB,
638 0x3B, 0x7B, 0xBB, 0xFC,
639 0x3C, 0x7C, 0xBC, 0xFD,
640 0x3D, 0x7D, 0xBD, 0xFE,
641 0x3E, 0x7E, 0xBE, 0xFF,
642 0x3F, 0x7F, 0xBF, 0x00,
643 0x40, 0x80, 0xC0, 0x01,
644 0x41, 0x81, 0xC1, 0x02,
645 0x42, 0x82, 0xC2, 0x03,
646 0x43, 0x83, 0xC3, 0x04,
647 0x44, 0x84, 0xC4, 0x05,
648 0x45, 0x85, 0xC5, 0x06,
649 0x46, 0x86, 0xC6, 0x07,
650 0x47, 0x87, 0xC7, 0x08,
651 0x48, 0x88, 0xC8, 0x09,
652 0x49, 0x89, 0xC9, 0x0A,
653 0x4A, 0x8A, 0xCA, 0x0B,
654 0x4B, 0x8B, 0xCB, 0x0C,
655 0x4C, 0x8C, 0xCC, 0x0D,
656 0x4D, 0x8D, 0xCD, 0x0E,
657 0x4E, 0x8E, 0xCE, 0x0F,
658 0x4F, 0x8F, 0xCF, 0x10,
659 0x50, 0x90, 0xD0, 0x11,
660 0x51, 0x91, 0xD1, 0x12,
661 0x52, 0x92, 0xD2, 0x13,
662 0x53, 0x93, 0xD3, 0x14,
663 0x54, 0x94, 0xD4, 0x15,
664 0x55, 0x95, 0xD5, 0x16,
665 0x56, 0x96, 0xD6, 0x17,
666 0x57, 0x97, 0xD7, 0x18,
667 0x58, 0x98, 0xD8, 0x19,
668 0x59, 0x99, 0xD9, 0x1A,
669 0x5A, 0x9A, 0xDA, 0x1B,
670 0x5B, 0x9B, 0xDB, 0x1C,
671 0x5C, 0x9C, 0xDC, 0x1D,
672 0x5D, 0x9D, 0xDD, 0x1E,
673 0x5E, 0x9E, 0xDE, 0x1F,
674 0x5F, 0x9F, 0xDF, 0x20,
675 0x60, 0xA0, 0xE0, 0x21,
676 0x61, 0xA1, 0xE1, 0x22,
677 0x62, 0xA2, 0xE2, 0x23,
678 0x63, 0xA3, 0xE3, 0x24,
679 0x64, 0xA4, 0xE4, 0x25,
680 0x65, 0xA5, 0xE5, 0x26,
681 0x66, 0xA6, 0xE6, 0x27,
682 0x67, 0xA7, 0xE7, 0x28,
683 0x68, 0xA8, 0xE8, 0x29,
684 0x69, 0xA9, 0xE9, 0x2A,
685 0x6A, 0xAA, 0xEA, 0x2B,
686 0x6B, 0xAB, 0xEB, 0x2C,
687 0x6C, 0xAC, 0xEC, 0x2D,
688 0x6D, 0xAD, 0xED, 0x2E,
689 0x6E, 0xAE, 0xEE, 0x2F,
690 0x6F, 0xAF, 0xEF, 0x30,
691 0x70, 0xB0, 0xF0, 0x31,
692 0x71, 0xB1, 0xF1, 0x32,
693 0x72, 0xB2, 0xF2, 0x33,
694 0x73, 0xB3, 0xF3, 0x34,
695 0x74, 0xB4, 0xF4, 0x35,
696 0x75, 0xB5, 0xF5, 0x36,
697 0x76, 0xB6, 0xF6, 0x37,
698 0x77, 0xB7, 0xF7, 0xF8
699];
700
701const BMV_AUDIO_STEPS: [[i16; 32]; 16] = [
702 [
703 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00,
704 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
705 -0x4000, -0x3C00, -0x3800, -0x3400, -0x3000, -0x2C00, -0x2800, -0x2400,
706 -0x2000, -0x1C00, -0x1800, -0x1400, -0x1000, -0x0C00, -0x0800, -0x0400
707 ], [
708 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0A00, 0x0C00, 0x0E00,
709 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1A00, 0x1C00, 0x1E00,
710 -0x2000, -0x1E00, -0x1C00, -0x1A00, -0x1800, -0x1600, -0x1400, -0x1200,
711 -0x1000, -0x0E00, -0x0C00, -0x0A00, -0x0800, -0x0600, -0x0400, -0x0200
712 ], [
713 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
714 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00,
715 -0x1000, -0x0F00, -0x0E00, -0x0D00, -0x0C00, -0x0B00, -0x0A00, -0x0900,
716 -0x0800, -0x0700, -0x0600, -0x0500, -0x0400, -0x0300, -0x0200, -0x0100
717 ], [
718 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380,
719 0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
720 -0x800, -0x780, -0x700, -0x680, -0x600, -0x580, -0x500, -0x480,
721 -0x400, -0x380, -0x300, -0x280, -0x200, -0x180, -0x100, -0x080
722 ], [
723 0x000, 0x048, 0x090, 0x0D8, 0x120, 0x168, 0x1B0, 0x1F8,
724 0x240, 0x288, 0x2D0, 0x318, 0x360, 0x3A8, 0x3F0, 0x438,
725 -0x480, -0x438, -0x3F0, -0x3A8, -0x360, -0x318, -0x2D0, -0x288,
726 -0x240, -0x1F8, -0x1B0, -0x168, -0x120, -0x0D8, -0x090, -0x048
727 ], [
728 0x000, 0x030, 0x060, 0x090, 0x0C0, 0x0F0, 0x120, 0x150,
729 0x180, 0x1B0, 0x1E0, 0x210, 0x240, 0x270, 0x2A0, 0x2D0,
730 -0x300, -0x2D0, -0x2A0, -0x270, -0x240, -0x210, -0x1E0, -0x1B0,
731 -0x180, -0x150, -0x120, -0x0F0, -0x0C0, -0x090, -0x060, -0x030
732 ], [
733 0x000, 0x020, 0x040, 0x060, 0x080, 0x0A0, 0x0C0, 0x0E0,
734 0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0, 0x1E0,
735 -0x200, -0x1E0, -0x1C0, -0x1A0, -0x180, -0x160, -0x140, -0x120,
736 -0x100, -0x0E0, -0x0C0, -0x0A0, -0x080, -0x060, -0x040, -0x020
737 ], [
738 0x000, 0x016, 0x02C, 0x042, 0x058, 0x06E, 0x084, 0x09A,
739 0x0B0, 0x0C6, 0x0DC, 0x0F2, 0x108, 0x11E, 0x134, 0x14A,
740 -0x160, -0x14A, -0x134, -0x11E, -0x108, -0x0F2, -0x0DC, -0x0C6,
741 -0x0B0, -0x09A, -0x084, -0x06E, -0x058, -0x042, -0x02C, -0x016
742 ], [
743 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070,
744 0x080, 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0,
745 -0x100, -0x0F0, -0x0E0, -0x0D0, -0x0C0, -0x0B0, -0x0A0, -0x090,
746 -0x080, -0x070, -0x060, -0x050, -0x040, -0x030, -0x020, -0x010
747 ], [
748 0x00, 0x0B, 0x16, 0x21, 0x2C, 0x37, 0x42, 0x4D,
749 0x58, 0x63, 0x6E, 0x79, 0x84, 0x8F, 0x9A, 0xA5,
750 -0xB0, -0xA5, -0x9A, -0x8F, -0x84, -0x79, -0x6E, -0x63,
751 -0x58, -0x4D, -0x42, -0x37, -0x2C, -0x21, -0x16, -0x0B
752 ], [
753 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
754 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
755 -0x80, -0x78, -0x70, -0x68, -0x60, -0x58, -0x50, -0x48,
756 -0x40, -0x38, -0x30, -0x28, -0x20, -0x18, -0x10, -0x08
757 ], [
758 0x00, 0x06, 0x0C, 0x12, 0x18, 0x1E, 0x24, 0x2A,
759 0x30, 0x36, 0x3C, 0x42, 0x48, 0x4E, 0x54, 0x5A,
760 -0x60, -0x5A, -0x54, -0x4E, -0x48, -0x42, -0x3C, -0x36,
761 -0x30, -0x2A, -0x24, -0x1E, -0x18, -0x12, -0x0C, -0x06
762 ], [
763 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
764 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
765 -0x40, -0x3C, -0x38, -0x34, -0x30, -0x2C, -0x28, -0x24,
766 -0x20, -0x1C, -0x18, -0x14, -0x10, -0x0C, -0x08, -0x04
767 ], [
768 0x00, 0x02, 0x05, 0x08, 0x0B, 0x0D, 0x10, 0x13,
769 0x16, 0x18, 0x1B, 0x1E, 0x21, 0x23, 0x26, 0x29,
770 -0x2C, -0x2A, -0x27, -0x24, -0x21, -0x1F, -0x1C, -0x19,
771 -0x16, -0x14, -0x11, -0x0E, -0x0B, -0x09, -0x06, -0x03
772 ], [
773 0x00, 0x01, 0x03, 0x05, 0x07, 0x08, 0x0A, 0x0C,
774 0x0E, 0x0F, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A,
775 -0x1C, -0x1B, -0x19, -0x17, -0x15, -0x14, -0x12, -0x10,
776 -0x0E, -0x0D, -0x0B, -0x09, -0x07, -0x06, -0x04, -0x02
777 ], [
778 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
779 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
780 -0x10, -0x0F, -0x0E, -0x0D, -0x0C, -0x0B, -0x0A, -0x09,
781 -0x08, -0x07, -0x06, -0x05, -0x04, -0x03, -0x02, -0x01
782 ]
783];