1const STEP_TABLE: [i16; 89] = [
3 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66,
4 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
5 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272,
6 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,
7 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767,
8];
9
10const INDEX_TABLE: [i8; 16] = [-1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8];
11
12#[derive(Debug, Clone, Copy)]
14pub struct AdpcmDecoder {
15 predictor: i16,
16 index: u8,
17 nibble_high: bool,
18 current_byte: u8,
19}
20
21impl AdpcmDecoder {
22 pub fn new(predictor: i16, index: u8) -> Self {
23 Self {
24 predictor,
25 index: index.min(88),
26 nibble_high: true,
27 current_byte: 0,
28 }
29 }
30
31 pub fn decode_nibble(&mut self, nibble: u8) -> i8 {
32 let nibble = nibble & 0x0F;
33 let step = STEP_TABLE[self.index as usize];
34 let mut diff = step >> 3;
35 if nibble & 4 != 0 {
36 diff += step;
37 }
38 if nibble & 2 != 0 {
39 diff += step >> 1;
40 }
41 if nibble & 1 != 0 {
42 diff += step >> 2;
43 }
44 if nibble & 8 != 0 {
45 self.predictor = (self.predictor as i32 - diff as i32).clamp(-32768, 32767) as i16;
46 } else {
47 self.predictor = (self.predictor as i32 + diff as i32).clamp(-32768, 32767) as i16;
48 }
49 let idx = self.index as i32 + INDEX_TABLE[nibble as usize] as i32;
50 self.index = idx.clamp(0, 88) as u8;
51 (self.predictor >> 8).clamp(-128, 127) as i8
52 }
53
54 fn next_from_bytes(&mut self, bytes: &mut &[u8]) -> Option<i8> {
55 if self.nibble_high {
56 let b = *bytes.first()?;
57 self.current_byte = *bytes.first()?;
58 *bytes = &bytes[1..];
59 self.nibble_high = false;
60 Some(self.decode_nibble(b >> 4))
61 } else {
62 self.nibble_high = true;
63 Some(self.decode_nibble(self.current_byte))
64 }
65 }
66}
67
68#[derive(Debug, Clone, Copy)]
70pub struct AdpcmStream<'a> {
71 payload: &'a [u8],
72 bytes: &'a [u8],
73 decoder: AdpcmDecoder,
74 looped: bool,
75}
76
77impl<'a> AdpcmStream<'a> {
78 pub fn new(payload: &'a [u8], flags: u8) -> Option<Self> {
79 if payload.len() < 4 {
80 return None;
81 }
82 let predictor = i16::from_le_bytes([payload[0], payload[1]]);
83 let index = payload[2];
84 let decoder = AdpcmDecoder::new(predictor, index);
85 Some(Self {
86 payload,
87 bytes: &payload[4..],
88 decoder,
89 looped: flags & crate::tier::flags::LOOP != 0,
90 })
91 }
92
93 fn rewind(&mut self) {
94 if let Some(s) = Self::new(self.payload, crate::tier::flags::LOOP) {
95 *self = s;
96 }
97 }
98
99 pub fn is_done(&self) -> bool {
100 self.bytes.is_empty() && !self.looped
101 }
102}
103
104impl<'a> AdpcmStream<'a> {
105 pub fn next_sample(&mut self) -> Option<i8> {
106 if self.bytes.is_empty() {
107 if self.looped {
108 self.rewind();
109 } else {
110 return None;
111 }
112 }
113 let mut slice = self.bytes;
114 let sample = self.decoder.next_from_bytes(&mut slice)?;
115 self.bytes = slice;
116 Some(sample)
117 }
118}