audio_codec_algorithms/
adpcm_ima.rs

1
2#[cfg(feature = "internal-no-panic")]
3use no_panic::no_panic;
4
5use crate::Error;
6
7/// State values for the IMA ADPCM encoder and decoder.
8///
9/// The values should be initialized to zeros or to values from the audio stream.
10#[derive(Debug, Clone, PartialEq)]
11pub struct AdpcmImaState {
12    pub predictor: i16,
13    pub step_index: u8,
14}
15
16impl AdpcmImaState {
17    /// Creates a new AdpcmState with zero values.
18    pub fn new() -> AdpcmImaState {
19        AdpcmImaState {
20            predictor: 0,
21            step_index: 0,
22        }
23    }
24}
25
26impl Default for AdpcmImaState {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32const IMA_INDEX_TABLE: &[i8; 16] = &[
33    -1, -1, -1, -1, 2, 4, 6, 8,
34    -1, -1, -1, -1, 2, 4, 6, 8
35];
36
37const IMA_STEP_TABLE: &[i16; 89] = &[
38    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
39    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
40    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
41    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
42    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
43    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
44    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
45    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
46    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
47];
48
49/// Decodes a 4-bit encoded IMA ADPCM value to a linear 16-bit signed integer sample value.
50///
51/// Only the lowest 4 bits of `encoded_nibble` are used and the top-most bits are ignored.
52///
53/// The `state` parameter should be initialized to zero or to values from the audio stream
54/// (depending on how the format has specified it). This method updates `state`
55/// with new values. Subsequent calls should pass in the state values from the previous call.
56#[cfg_attr(feature = "internal-no-panic", no_panic)]
57#[inline(always)]
58pub fn decode_adpcm_ima(encoded_nibble: u8, state: &mut AdpcmImaState) -> i16 {
59    let nibble = encoded_nibble & 0x0f; // ensure nibble is in the range 0..=15
60    state.step_index = state.step_index.min(88); // validate step_index
61
62    // calculate the sample value (predictor) from the previous predictor, step and nibble
63    let step_size = i32::from(IMA_STEP_TABLE[usize::from(state.step_index)]);
64    let mut diff = step_size >> 3;
65    if (nibble & 4) != 0 { diff += step_size; }
66    if (nibble & 2) != 0 { diff += step_size >> 1; }
67    if (nibble & 1) != 0 { diff += step_size >> 2; }
68    let mut predictor = i32::from(state.predictor);
69    if (nibble & 8) != 0 {
70        predictor -= diff;
71    } else {
72        predictor += diff;
73    }
74    // store predictor for the next round, clamped to i16
75    #[allow(clippy::cast_possible_truncation)] // value is clamped so truncation never happens
76    {
77    state.predictor = predictor.clamp(-32768, 32767) as i16;
78    }
79    // adjust step index, clamped to 0..=88
80    state.step_index = state.step_index
81        .saturating_add_signed(IMA_INDEX_TABLE[usize::from(nibble)])
82        .min(88);
83    // predictor is the decoded sample value
84    state.predictor
85}
86
87/// Decodes an AIFF-C / QT "ima4" compressed block to 16-bit signed integer samples.
88///
89/// `buf` should contain 2 header bytes (predictor and step index) and 32 bytes of 4-bit samples.
90///
91/// The `state` parameter should be initialized to zero for the first call and subsequent calls
92/// should pass in the state values from the previous call.
93///
94/// This function outputs 64 decoded samples to `out_samples`.
95#[cfg_attr(feature = "internal-no-panic", no_panic)]
96#[inline(always)]
97pub fn decode_adpcm_ima_ima4(buf: &[u8; 34], state: &mut AdpcmImaState,
98    out_samples: &mut [i16; 64]) {
99
100    // the first two bytes are the initial state: pppppppp piiiiiii
101    let predictor = i16::from_be_bytes([ buf[0], buf[1] & 0b1000_0000 ]);
102    // clamp to the same range as macOS AudioToolbox Framework (0..=88)
103    let step_index = (buf[1] & 0b0111_1111).min(88);
104    // use the previous block's last sample value as the predictor instead of
105    // block header's predictor, if the last sample value is close enough the block header's
106    // predictor - this increases the decoding accuracy.
107    // note that this means that the sample values of the previous block will affect later blocks.
108    // this implementation seems to match Audio Toolbox framework.
109    if state.step_index != step_index ||
110        state.predictor < predictor.saturating_sub(127) ||
111        state.predictor > predictor.saturating_add(127) {
112        state.predictor = predictor;
113        state.step_index = step_index;
114    }
115    // decode the rest of the block as nibbles
116    let mut sample_index = 0;
117    for b in &buf[2..] {
118        let s0 = decode_adpcm_ima(*b & 0x0f, state);
119        out_samples[sample_index] = s0;
120        sample_index += 1;
121        let s1 = decode_adpcm_ima(*b >> 4, state);
122        out_samples[sample_index] = s1;
123        sample_index += 1;
124    }
125}
126
127/// Decodes WAV / MS IMA ADPCM (wav format 0x0011) compressed block to
128/// 16-bit signed integer samples.
129///
130/// `buf` should contain header bytes (predictor and step index) and bytes of 4-bit encoded
131/// samples. For 1 channel audio, the `buf` length must be at least 4. For 2 channel audio,
132/// the `buf` length must be at least 8 and it must be divisible by 8.
133/// The `buf` length must always be less than 65536.
134///
135/// `is_stereo` should be `false` for 1 channel (mono) audio and `true` for
136/// 2 channel (stereo) audio.
137///
138/// This function outputs decoded samples to `out_samples`. The `out_samples` length must be
139/// `2 * buf.len() - 7` for 1 channel audio and `2 * buf.len() - 14` for 2 channel audio.
140/// Samples are interleaved for 2 channel audio.
141///
142/// An error is returned if the `buf` or `out_samples` length isn't correct.
143/// If an error is returned, `out_samples` is left unmodified.
144pub fn decode_adpcm_ima_ms(buf: &[u8], is_stereo: bool, out_samples: &mut [i16])
145    -> Result<(), Error> {
146
147    let channels = if is_stereo {
148        2
149    } else {
150        1
151    };
152    // check buf length
153    if (channels == 1 && buf.len() < 4) ||
154        (channels == 2 && (buf.len() < 8 || buf.len() % 8 != 0)) {
155        return Err(Error::InvalidBufferSize);
156    }
157    if buf.len() > 0xffff {
158        return Err(crate::Error::InvalidBufferSize);
159    }
160    // check that the length of the input buffer and output buffer match
161    let expected_sample_len = (buf.len() - 4 * channels)
162        .checked_mul(2)
163        .and_then(|v| v.checked_add(channels))
164        .ok_or(Error::InvalidBufferSize)?;
165    if expected_sample_len != out_samples.len() {
166        return Err(Error::InvalidBufferSize);
167    }
168    let mut states = [ AdpcmImaState::new(), AdpcmImaState::new() ];
169    // the first channels*4 bytes are the initial state (every fourth byte is ignored)
170    for ch in 0..channels {
171        states[ch].predictor = i16::from_le_bytes([ buf[ch*4], buf[ch*4+1] ]);
172        // Windows 10 acmStreamConvert() refuses to convert blocks which have step index > 88
173        // and Windows Media Player ignores such blocks.
174        // macOS and Audacity clamp step index to 0..=88. Let's copy that behavior here so that
175        // something is decoded.
176        states[ch].step_index = buf[ch*4+2].min(88);
177        out_samples[ch] = states[ch].predictor;
178    }
179    // decode the rest of the block from nibbles to interleaved samples
180    let mut out_index = 0;
181    let mut ch = 0;
182    let mut out_subindex = 0;
183    for b in &buf[4*channels..] {
184        let pos = channels + out_index*4*channels*channels + out_subindex*channels + ch;
185        out_samples[pos] = decode_adpcm_ima(*b & 0x0f, &mut states[ch]);
186        out_samples[pos + channels] = decode_adpcm_ima(*b >> 4, &mut states[ch]);
187        out_subindex += 2;
188        if out_subindex == 4*channels {
189            out_subindex = 0;
190            ch += 1;
191            if ch == channels {
192                ch = 0;
193                out_index += 1;
194            }
195        }
196    }
197    Ok(())
198}
199
200/// Encodes a linear 16-bit signed integer sample value to a 4-bit encoded IMA ADPCM value.
201///
202/// The `state` parameter should be initialized to zero or to values from the audio stream
203/// (depending on how the format has specified it). This method updates `state`
204/// with new values. Subsequent calls should pass in the state values from the previous call.
205#[cfg_attr(feature = "internal-no-panic", no_panic)]
206#[inline(always)]
207pub fn encode_adpcm_ima(sample_value: i16, state: &mut AdpcmImaState) -> u8 {
208    state.step_index = state.step_index.min(88); // validate step_index
209
210    // calculate the output nibble using the sample value, previous predictor value and step
211
212    let mut diff = i32::from(sample_value) - i32::from(state.predictor);
213    let mut nibble: u8;
214    if diff >= 0 {
215        nibble = 0;
216    } else {
217        nibble = 8;
218        diff = -diff;
219    }
220    // calculate nibble and predictor_diff
221    // nibble bit 4, predictor_diff step_size
222    let step_size = i32::from(IMA_STEP_TABLE[usize::from(state.step_index)]);
223    let mut predictor_diff: i32 = step_size >> 3;
224    let mut temp_step_size = step_size;
225    if diff >= temp_step_size {
226        nibble |= 4;
227        predictor_diff += step_size;
228        diff -= temp_step_size;
229    }
230    // nibble bit 2, predictor_diff step_size/2
231    temp_step_size >>= 1;
232    if diff >= temp_step_size {
233        nibble |= 2;
234        predictor_diff += step_size >> 1;
235        diff -= temp_step_size;
236    }
237    // nibble bit 1, predictor_diff step_size/4
238    temp_step_size >>= 1;
239    if diff >= temp_step_size {
240        nibble |= 1;
241        predictor_diff += step_size >> 2;
242    }
243
244    // update the predicted sample (predictor)
245    let mut predictor = i32::from(state.predictor);
246    if (nibble & 8) == 8 {
247        predictor -= predictor_diff;
248    } else {
249        predictor += predictor_diff;
250    }
251    // store predictor for the next round, clamped to i16
252    #[allow(clippy::cast_possible_truncation)] // value is clamped so truncation never happens
253    {
254    state.predictor = predictor.clamp(-32768, 32767) as i16;
255    }
256    // adjust step index, clamped to 0..=88
257    state.step_index = state.step_index
258        .saturating_add_signed(IMA_INDEX_TABLE[usize::from(nibble)])
259        .min(88);
260    // nibble is the encoded value
261    nibble
262}
263
264/// Encodes 16-bit signed integer samples to an AIFF-C / QT "ima4" compressed block.
265///
266/// The `state` parameter should be initialized to zero for the first call and subsequent calls
267/// should pass in the state values from the previous call.
268///
269/// This function outputs 34 encoded bytes to `out_buf`: 2 header bytes (predictor and step index)
270/// and 32 bytes of 4-bit samples.
271#[cfg_attr(feature = "internal-no-panic", no_panic)]
272#[inline(always)]
273pub fn encode_adpcm_ima_ima4(samples: &[i16; 64], state: &mut AdpcmImaState,
274    out_buf: &mut [u8; 34]) {
275
276    state.step_index = state.step_index.min(88);
277    // the first two bytes are the initial state: pppppppp piiiiiii
278    #[allow(clippy::cast_sign_loss)] // sign loss is expected when splitting the values to bytes
279    {
280    out_buf[0] = (state.predictor >> 8) as u8;
281    out_buf[1] = (state.predictor & 0x80) as u8 | state.step_index;
282    }
283    // encode 64 samples to 64 nibbles (32 bytes)
284    let mut sample_index = 0;
285    for out_b in &mut out_buf[2..] {
286        let nibble0 = encode_adpcm_ima(samples[sample_index], state);
287        sample_index += 1;
288        let nibble1 = encode_adpcm_ima(samples[sample_index], state);
289        sample_index += 1;
290        *out_b = nibble1 << 4 | nibble0;
291    }
292}
293
294/// Encodes 16-bit signed integer samples to a MS / WAV IMA ADPCM (wav format 0x0011)
295/// compressed block.
296///
297/// Only 1 or 2 channel audio data is supported. For 1 channel audio, there must be an odd number
298/// of samples (1, 3, 5, ..) and for 2 channel audio, `samples` length must be divisible by 16
299/// after subtracting 2 from it (2, 18, 34, 50, 66, ..).
300/// Samples must be interleaved for 2 channel audio.
301///
302/// `states` must contain channel number of `AdpcmImaState` items (1 or 2). The state objects
303/// should be initialized to zero for the first call and subsequent calls
304/// should pass in the state values from the previous call.
305///
306/// This function outputs encoded bytes to `out_buf`. The `out_buf` length must be
307/// `((samples.len() - states.len()) / 2) + states.len()*4` and less than 65536.
308///
309/// Usually, for 1 channel (mono) audio, the `out_buf` length is 1024 and
310/// the `samples` length is 2041.
311/// For 2 channel (stereo) audio, the `out_buf` length is 2048 and the `samples` length is 4082.
312///
313/// An error is returned if `states` has an invalid number of state objects or
314/// if the `samples` or `out_buf` length isn't correct.
315/// If an error is returned, `out_buf` is left unmodified.
316pub fn encode_adpcm_ima_ms(samples: &[i16], states: &mut [AdpcmImaState], out_buf: &mut [u8])
317    -> Result<(), Error> {
318    let channels = states.len();
319    if channels < 1 || channels > 2 {
320        return Err(crate::Error::InvalidChannels);
321    }
322    // check samples length
323    if (channels == 1 && samples.len() & 1 == 0) ||
324        (channels == 2 && (samples.len() < 2 || (samples.len()-2) % 16 != 0)) {
325        return Err(crate::Error::InvalidBufferSize);
326    }
327    // check buf length
328    if out_buf.len() > 0xffff {
329        return Err(crate::Error::InvalidBufferSize);
330    }
331    // check that the length of the input buffer and output buffer match
332    if ((samples.len() - states.len()) / 2) + states.len()*4 != out_buf.len() {
333        return Err(crate::Error::InvalidBufferSize);
334    }
335    // the first channels*4 bytes are the initial state (every fourth byte is ignored)
336    for ch in 0..channels {
337        states[ch].predictor = samples[ch];
338        //note: the value of states[ch].step_index is used from the function argument
339        out_buf[ch*4] = samples[ch].to_le_bytes()[0];
340        out_buf[ch*4+1] = samples[ch].to_le_bytes()[1];
341        out_buf[ch*4+2] = states[ch].step_index;
342        out_buf[ch*4+3] = 0;
343    }
344    // encode interleaved samples to nibbles
345    let mut index = 0;
346    let mut ch = 0;
347    let mut subindex = 0;
348    for b in &mut out_buf[channels*4..] {
349        let pos = channels + index*4*channels*channels + subindex*channels + ch;
350        let s0 = encode_adpcm_ima(samples[pos], &mut states[ch]);
351        let s1 = encode_adpcm_ima(samples[pos+channels], &mut states[ch]);
352        *b = s0 | (s1 << 4);
353        subindex += 2;
354        if subindex == 4*channels {
355            subindex = 0;
356            ch += 1;
357            if ch == channels {
358                ch = 0;
359                index += 1;
360            }
361        }
362    }
363    Ok(())
364}
365
366#[cfg(test)]
367mod tests {
368    use super::*;
369
370    #[test]
371    fn test_decode_adpcm_ima() {
372        // normal decoding
373        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
374        assert_eq!(decode_adpcm_ima(6, &mut state), 10);
375        assert_eq!(state, AdpcmImaState { predictor: 10, step_index: 6 });
376
377        // tests that resulting step index is clamped to 0
378        let mut state = AdpcmImaState { predictor: 200, step_index: 0 };
379        assert_eq!(decode_adpcm_ima(3, &mut state), 204);
380        assert_eq!(state, AdpcmImaState { predictor: 204, step_index: 0 });
381
382        // tests that resulting step index is clamped to 88
383        let mut state = AdpcmImaState { predictor: 20200, step_index: 84 };
384        assert_eq!(decode_adpcm_ima(14, &mut state), -16175);
385        assert_eq!(state, AdpcmImaState { predictor: -16175, step_index: 88 });
386
387        // tests that the returned sample is clamped to -32768
388        let mut state = AdpcmImaState { predictor: -30123, step_index: 80 };
389        assert_eq!(decode_adpcm_ima(14, &mut state), -32768);
390        assert_eq!(state, AdpcmImaState { predictor: -32768, step_index: 86 });
391
392        // tests that the returned sample is clamped to 32767
393        let mut state = AdpcmImaState { predictor: 30123, step_index: 80 };
394        assert_eq!(decode_adpcm_ima(7, &mut state), 32767);
395        assert_eq!(state, AdpcmImaState { predictor: 32767, step_index: 88 });
396
397        // check nibble value too large (greater than 15)
398        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
399        assert_eq!(decode_adpcm_ima(16, &mut state), 0);
400        assert_eq!(state, AdpcmImaState { predictor: 0, step_index: 0 });
401
402        // check input step index too large
403        let mut state = AdpcmImaState { predictor: 0, step_index: 89 };
404        assert_eq!(decode_adpcm_ima(10, &mut state), -20478);
405        assert_eq!(state, AdpcmImaState { predictor: -20478, step_index: 87 });
406    }
407
408    #[test]
409    fn test_decode_adpcm_ima4() {
410        // macOS 14 afconvert has been tested to return the same values
411
412        // simple block
413        let mut decoded_buf = [0i16; 64];
414        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
415        decode_adpcm_ima_ima4(&[ 0x00, 0x00,
416            0x06, 0x08, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
417            0xFF, 0x08, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
418            0x01, 0x00, 0x01, 0x11, 0x11, 0x11, 0x22, 0x22,
419            0x32, 0x43, 0x33, 0x43, 0x43, 0x42, 0x32, 0x43
420        ], &mut state, &mut decoded_buf);
421        assert_eq!(decoded_buf, [
422            10, 11, 10, 11, 10, 11, 10, 10,
423            -1, -31, -94, -230, -523, -1154, -2511, -5421,
424            -11657, -25029, -26940, -25203, -23624, -25059, -23754, -22568,
425            -21490, -22470, -21579, -20769, -20033, -19364, -18756, -18203,
426            -16694, -16237, -15822, -15444, -14414, -14102, -13250, -12476,
427            -11773, -11134, -10552, -10024, -9223, -8495, -7833, -7232,
428            -6685, -5989, -5356, -4616, -3920, -3287, -2712, -2040,
429            -1407, -667, -170, 644, 1191, 1887, 2520, 3260,
430        ]);
431        assert_eq!(state, AdpcmImaState { predictor: 3260, step_index: 49 });
432
433        // the previous state (0x0cbc, 49) is given to the next call to check that it is used
434        decode_adpcm_ima_ima4(&[ 0x0C, 0xB1,
435            0x42, 0x32, 0x43, 0x42, 0x32, 0x43, 0x42, 0x32,
436            0x43, 0x42, 0x32, 0x43, 0x42, 0x32, 0x33, 0x34,
437            0x34, 0x33, 0x34, 0x34, 0x33, 0x34, 0xF5, 0xFF,
438            0xEF, 0x80, 0x00, 0x08, 0x80, 0x00, 0x08, 0x80
439        ], &mut state, &mut decoded_buf);
440        assert_eq!(decoded_buf, [
441            3757, 4571, 5118, 5814, 6447, 7187, 7684, 8498,
442            9045, 9741, 10374, 11114, 11611, 12425, 12972, 13668,
443            14301, 15041, 15538, 16352, 16899, 17595, 18228, 18968,
444            19465, 20279, 20826, 21522, 22155, 22730, 23402, 24035,
445            24775, 25471, 26104, 26679, 27351, 27984, 28724, 29420,
446            30053, 30628, 31300, 31933, 32767, 30963, 27090, 18788,
447            990, -32078, -27983, -31707, -28322, -25245, -28043, -25500,
448            -23188, -25290, -23379, -21642, -23221, -21786, -20481, -21667,
449        ]);
450        assert_eq!(state, AdpcmImaState { predictor: -21667, step_index: 74 });
451
452        // passing in zero state with the same block will give different results
453        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
454        decode_adpcm_ima_ima4(&[ 0x0C, 0xB1,
455            0x42, 0x32, 0x43, 0x42, 0x32, 0x43, 0x42, 0x32,
456            0x43, 0x42, 0x32, 0x43, 0x42, 0x32, 0x33, 0x34,
457            0x34, 0x33, 0x34, 0x34, 0x33, 0x34, 0xF5, 0xFF,
458            0xEF, 0x80, 0x00, 0x08, 0x80, 0x00, 0x08, 0x80
459        ], &mut state, &mut decoded_buf);
460        assert_eq!(decoded_buf, [
461            3697, 4511, 5058, 5754, 6387, 7127, 7624, 8438,
462            8985, 9681, 10314, 11054, 11551, 12365, 12912, 13608,
463            14241, 14981, 15478, 16292, 16839, 17535, 18168, 18908,
464            19405, 20219, 20766, 21462, 22095, 22670, 23342, 23975,
465            24715, 25411, 26044, 26619, 27291, 27924, 28664, 29360,
466            29993, 30568, 31240, 31873, 32767, 30963, 27090, 18788,
467            990, -32078, -27983, -31707, -28322, -25245, -28043, -25500,
468            -23188, -25290, -23379, -21642, -23221, -21786, -20481, -21667
469        ]);
470        assert_eq!(state, AdpcmImaState { predictor: -21667, step_index: 74 });
471
472        // second packet's last sample 127 matches the next packet's predictor 0,
473        // which means that 127 is used as the decoded sample value instead of 0
474        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
475        decode_adpcm_ima_ima4(&[0, 0,
476            182, 179, 195, 180, 178, 196, 179, 179,
477            89, 107, 59, 76, 59, 75, 60, 59,
478            45, 47, 63, 63, 63, 63, 63, 63,
479            63, 63, 63, 60, 59, 76, 59, 43,
480        ], &mut state, &mut decoded_buf);
481        assert_eq!(decoded_buf, [
482            10, 0, 10, 2, 10, 0, 12, 2,
483            9, 1, 12, -1, 10, 0, 10, 2,
484            -1, 11, 1, 20, 3, 18, -1, 22,
485            1, 19, 2, 23, -2, 22, 1, 19,
486            -9, 9, -43, -6, -107, -5, -204, -4,
487            -395, -3, -768, -2, -1494, -2, -2912, -3,
488            -5673, 0, -11050, 4, -21532, 11, -25172, -1473,
489            -23016, -3430, -26323, 1377, -24692, -993, -22536, -8546
490        ]);
491        assert_eq!(state, AdpcmImaState { predictor: -8546, step_index: 83 });
492        decode_adpcm_ima_ima4(&[0, 41,
493            8, 8, 128, 128, 8, 8, 128, 8,
494            128, 8, 128, 128, 128, 128, 8, 9,
495            8, 3, 8, 8, 8, 6, 4, 3,
496            4, 3, 4, 5, 3, 3, 3, 3,
497        ], &mut state, &mut decoded_buf);
498        assert_eq!(decoded_buf, [
499            -46, -4, -42, -8, 23, -5, 21, -2,
500            -23, -4, -21, -5, 9, -4, -16, -5,
501            5, -4, -12, -5, 1, -5, 0, -5,
502            -1, -5, -2, -5, -8, -6, -13, -11,
503            -13, -11, 0, 1, 0, 1, 0, 1,
504            0, 0, 10, 11, 24, 25, 35, 36,
505            48, 49, 59, 60, 71, 72, 86, 88,
506            99, 100, 110, 111, 119, 120, 127, 127
507        ]);
508        assert_eq!(state, AdpcmImaState { predictor: 127, step_index: 0 });
509        decode_adpcm_ima_ima4(&[0, 0,
510            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
511            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
512        ], &mut state, &mut decoded_buf);
513        assert_eq!(decoded_buf, [
514            127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
515            127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
516            127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
517            127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127
518        ]);
519
520        // second packet's sample -127 matches the next packet's predictor 0,
521        // which means that -127 is used as the decoded sample value instead of 0
522        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
523        decode_adpcm_ima_ima4(&[0, 0,
524            182, 179, 195, 180, 178, 196, 179, 179, 89, 107, 59, 76, 59, 75, 60, 59,
525            45, 47, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 59, 76, 59, 43,
526        ], &mut state, &mut decoded_buf);
527        assert_eq!(decoded_buf, [
528            10, 0, 10, 2, 10, 0, 12, 2,
529            9, 1, 12, -1, 10, 0, 10, 2,
530            -1, 11, 1, 20, 3, 18, -1, 22,
531            1, 19, 2, 23, -2, 22, 1, 19,
532            -9, 9, -43, -6, -107, -5, -204, -4,
533            -395, -3, -768, -2, -1494, -2, -2912, -3,
534            -5673, 0, -11050, 4, -21532, 11, -25172, -1473,
535            -23016, -3430, -26323, 1377, -24692, -993, -22536, -8546
536        ]);
537        assert_eq!(state, AdpcmImaState { predictor: -8546, step_index: 83 });
538        decode_adpcm_ima_ima4(&[0, 41,
539            8, 8, 128, 128, 8, 8, 128, 8, 128, 8, 128, 128, 128, 128, 11, 11,
540            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10,
541        ], &mut state, &mut decoded_buf);
542        assert_eq!(decoded_buf, [
543            -46, -4, -42, -8, 23, -5, 21, -2,
544            -23, -4, -21, -5, 9, -4, -16, -5,
545            5, -4, -12, -5, 1, -5, 0, -5,
546            -1, -5, -2, -5, -26, -24, -41, -39,
547            -53, -51, -62, -61, -71, -70, -78, -77,
548            -84, -84, -88, -88, -92, -92, -96, -96,
549            -100, -100, -104, -104, -108, -108, -112, -112,
550            -116, -116, -120, -120, -124, -124, -127, -127
551        ]);
552        assert_eq!(state, AdpcmImaState { predictor: -127, step_index: 0 });
553        decode_adpcm_ima_ima4(&[0, 0,
554            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
555            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
556        ], &mut state, &mut decoded_buf);
557        assert_eq!(decoded_buf, [
558            -127, -127, -127, -127, -127, -127, -127, -127,
559            -127, -127, -127, -127, -127, -127, -127, -127,
560            -127, -127, -127, -127, -127, -127, -127, -127,
561            -127, -127, -127, -127, -127, -127, -127, -127,
562            -127, -127, -127, -127, -127, -127, -127, -127,
563            -127, -127, -127, -127, -127, -127, -127, -127,
564            -127, -127, -127, -127, -127, -127, -127, -127,
565            -127, -127, -127, -127, -127, -127, -127, -127
566        ]);
567
568        // out-of-bounds step index in buf is clamped
569        let mut decoded_buf = [0i16; 64];
570        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
571        decode_adpcm_ima_ima4(&[ 0x80, 0x59,
572            0x06, 0x08, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
573            0xFF, 0x08, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
574            0x01, 0x00, 0x01, 0x11, 0x11, 0x11, 0x22, 0x22,
575            0x32, 0x43, 0x33, 0x43, 0x43, 0x42, 0x32, 0x43
576        ], &mut state, &mut decoded_buf);
577        assert_eq!(decoded_buf, [
578            20477, 24572, 20848, 24233, 21156, 23954, 21411, 23723,
579            -7810, -32768, -32768, -32768, -32768, -32768, -32768, -32768,
580            -32768, -32768, -32768, -29044, -25659, -28736, -25938, -23395,
581            -21083, -23185, -21274, -19537, -17958, -16523, -15218, -14032,
582            -10797, -9817, -8926, -8116, -5907, -5238, -3413, -1753,
583            -244, 1128, 2374, 3508, 5225, 6786, 8206, 9497,
584            10670, 12162, 13520, 15107, 16599, 17957, 19190, 20632,
585            21990, 23577, 24643, 26389, 27562, 29054, 30412, 31999,
586        ]);
587        assert_eq!(state, AdpcmImaState { predictor: 31999, step_index: 57 });
588    }
589
590    #[test]
591    fn test_decode_adpcm_ms() {
592        // Windows 10 acmStreamConvert() has been tested to return the same values
593
594        // one channel
595        let mut samples = [0i16; 25];
596        assert!(decode_adpcm_ima_ms(&[ 0xAE, 0xC8, 0x40, 0x00,
597            0x10, 0x10, 0x10, 0x11, 0x21, 0x21, 0x22, 0x32, 0x43, 0x33, 0x43, 0x43
598        ], false, &mut samples).is_ok());
599        assert_eq!(samples, [
600            -14162, -13747, -12613, -12270, -11334, -11050, -10276, -9573, -8934, -8352,
601            -7471, -6991, -6263, -5601, -5000, -4453, -3757, -3124, -2384, -1688,
602            -1055, -480, 192, 825, 1565
603        ]);
604
605        // two channels
606        let mut samples = [0i16; 18];
607        assert!(decode_adpcm_ima_ms(&[  0x38, 0xB1, 0x47, 0x00,
608            0x1A, 0x9B, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x08
609        ], true, &mut samples).is_ok());
610        assert_eq!(samples, [
611            -20168, -25830, -19358, -23919, -18622, -22182, -17953, -23761, -17345, -22326,
612            -15685, -21021, -15182, -19835, -14725, -20913, -14310, -19933
613        ]);
614
615        // not enough input data for 1 channel audio
616        let mut samples = [0i16; 25];
617        assert!(matches!(decode_adpcm_ima_ms(&[ 0x38, 0xB1, 0x47
618        ], false, &mut samples), Err(Error::InvalidBufferSize)));
619
620        // invalid buf length for 2 channel audio
621        let mut samples = [0i16; 4];
622        assert!(matches!(decode_adpcm_ima_ms(&[ 0x38, 0xB1, 0x47, 0x00,
623            0x38, 0xB1, 0x47, 0x38, 0xB1
624        ], true, &mut samples), Err(Error::InvalidBufferSize)));
625
626        // out-of-bounds step index is clamped
627        // (acmStreamConvert() doesn't return any result for this, but some other libraries
628        // clamp out-of-bounds step indexes and this implementation matches that behavior)
629        let mut samples = [0i16; 25];
630        assert!(decode_adpcm_ima_ms(&[ 0x11, 0x81, 89, 0x00,
631            0x10, 0x10, 0x10, 0x11, 0x21, 0x21, 0x22, 0x32, 0x43, 0x33, 0x43, 0x43
632        ], false, &mut samples).is_ok());
633        assert_eq!(samples, [
634            -32495, -28400, -17228, -13843, -4611, -1813, 5817, 12754, 19060, 24793,
635            32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767,
636            32767, 32767, 32767, 32767, 32767
637        ]);
638
639        // invalid out_samples length
640        let mut samples = [0i16; 26];
641        assert!(matches!(decode_adpcm_ima_ms(&[ 0xAE, 0xC8, 0x40, 0x00,
642            0x10, 0x10, 0x10, 0x11, 0x21, 0x21, 0x22, 0x32, 0x43, 0x33, 0x43, 0x43
643        ], false, &mut samples), Err(Error::InvalidBufferSize)));
644
645        // 1 channel and buf size 1024 can be decoded to 2041 samples
646        let mut samples = [0i16; 2041];
647        assert!(decode_adpcm_ima_ms(&[0u8; 1024], false, &mut samples).is_ok());
648
649        // 2 channels and buf size 2048 can be decoded to 4082 samples
650        let mut samples = [0i16; 4082];
651        assert!(decode_adpcm_ima_ms(&[0u8; 2048], true, &mut samples).is_ok());
652    }
653
654    #[test]
655    fn test_decode_adpcm_ms_with_different_buf_sizes() {
656        let buf_area = [0u8; 4096];
657        let mut sample_area = [0i16; 8192];
658        // one channel
659        for buf_len in 0..=1025 {
660            let buf = &buf_area[0..buf_len];
661            let sample_len = 2 * buf.len().max(4) - 7 * 1;
662            let mut samples = &mut sample_area[0..sample_len];
663            if buf_len >= 4 {
664                assert!(decode_adpcm_ima_ms(&buf, false, &mut samples).is_ok());
665            } else {
666                assert!(matches!(decode_adpcm_ima_ms(&buf, false, &mut samples),
667                    Err(Error::InvalidBufferSize)));
668            }
669        }
670        // two channels
671        for buf_len in 0..=2049 {
672            let buf = &buf_area[0..buf_len];
673            let sample_len = 2 * buf.len().max(7) - 7 * 2;
674            let mut samples = &mut sample_area[0..sample_len];
675            if buf_len >= 8 && buf_len % 8 == 0 {
676                assert!(decode_adpcm_ima_ms(&buf, true, &mut samples).is_ok());
677            } else {
678                assert!(matches!(decode_adpcm_ima_ms(&buf, true, &mut samples),
679                    Err(Error::InvalidBufferSize)));
680            }
681        }
682    }
683
684    #[test]
685    fn test_encode_adpcm_ima() {
686        // normal encoding
687        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
688        assert_eq!(encode_adpcm_ima(10, &mut state), 6);
689        assert_eq!(state, AdpcmImaState { predictor: 10, step_index: 6 });
690
691        // tests that output step index is clamped to 0
692        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
693        assert_eq!(encode_adpcm_ima(0, &mut state), 0);
694        assert_eq!(state, AdpcmImaState { predictor: 0, step_index: 0 });
695
696        // tests that output step index is clamped to 88
697        let mut state = AdpcmImaState { predictor: -30350, step_index: 83 };
698        assert_eq!(encode_adpcm_ima(897, &mut state), 6);
699        assert_eq!(state, AdpcmImaState { predictor: 2718, step_index: 88 });
700
701        // tests that the returned sample is clamped to -32768
702        let mut state = AdpcmImaState { predictor: -32550, step_index: 65 };
703        assert_eq!(encode_adpcm_ima(-32697, &mut state), 8);
704        assert_eq!(state, AdpcmImaState { predictor: -32768, step_index: 64 });
705
706        // tests that the returned sample is clamped to 32767
707        let mut state = AdpcmImaState { predictor: 32700, step_index: 65 };
708        assert_eq!(encode_adpcm_ima(32760, &mut state), 0);
709        assert_eq!(state, AdpcmImaState { predictor: 32767, step_index: 64 });
710
711        // check passing in a step index with a too large value
712        let mut state = AdpcmImaState { predictor: 0, step_index: 89 };
713        assert_eq!(encode_adpcm_ima(0, &mut state), 0);
714        assert_eq!(state, AdpcmImaState { predictor: 4095, step_index: 87 });
715    }
716
717    #[test]
718    fn test_encode_adpcm_ima4() {
719        // macOS 14 afconvert has been tested to return the same values
720
721        // simple block with zero initial state values
722        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
723        let mut encoded_buf = [0u8; 34];
724        encode_adpcm_ima_ima4(&[
725            10, 10, 10, 10, 10, 10, 10, 10,
726            -32768, -32114, -31460, -30806, -30153, -29499, -28845, -28191,
727            -27537, -26883, -26229, -25575, -24922, -24268, -23614, -22960,
728            -22306, -21652, -20998, -20344, -19691, -19037, -18383, -17729,
729            -17075, -16421, -15767, -15113, -14460, -13806, -13152, -12498,
730            -11844, -11190, -10536, -9882, -9229, -8575, -7921, -7267,
731            -6613, -5959, -5305, -4651, -3998, -3344, -2690, -2036,
732            -1382, -728, -74, 580, 1233, 1887, 2541, 3195,
733        ], &mut state, &mut encoded_buf);
734        assert_eq!(encoded_buf, [ 0x00, 0x00,
735            0x06, 0x08, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
736            0xFF, 0x08, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
737            0x01, 0x00, 0x01, 0x11, 0x11, 0x11, 0x22, 0x22,
738            0x32, 0x43, 0x33, 0x43, 0x43, 0x42, 0x32, 0x43
739        ]);
740        assert_eq!(state, AdpcmImaState { predictor: 0x0cbc, step_index: 49 });
741
742        // the previous state (0x0cbc, 49) is given to the next call to check that it is used
743        encode_adpcm_ima_ima4(&[
744            3849, 4503, 5157, 5811, 6464, 7118, 7772, 8426,
745            9080, 9734, 10388, 11042, 11695, 12349, 13003, 13657,
746            14311, 14965, 15619, 16273, 16926, 17580, 18234, 18888,
747            19542, 20196, 20850, 21504, 22157, 22811, 23465, 24119,
748            24773, 25427, 26081, 26735, 27388, 28042, 28696, 29350,
749            30004, 30658, 31312, 31966, 32767, -32263, -31609, -30955,
750            -30301, -29647, -28993, -28339, -27686, -27032, -26378, -25724,
751            -25070, -24416, -23762, -23108, -22455, -21801, -21147, -20493,
752        ], &mut state, &mut encoded_buf);
753        assert_eq!(encoded_buf, [ 0x0C, 0xB1,
754            0x42, 0x32, 0x43, 0x42, 0x32, 0x43, 0x42, 0x32,
755            0x43, 0x42, 0x32, 0x43, 0x42, 0x32, 0x33, 0x34,
756            0x34, 0x33, 0x34, 0x34, 0x33, 0x34, 0xF5, 0xFF,
757            0xEF, 0x80, 0x00, 0x08, 0x80, 0x00, 0x08, 0x80
758        ]);
759        assert_eq!(state, AdpcmImaState { predictor: -21667, step_index: 74 });
760
761        // large sample values with initial zero state values
762        let mut state = AdpcmImaState { predictor: 0, step_index: 0 };
763        encode_adpcm_ima_ima4(&[
764            16000, 24000, 30000, 32000, 32000, 30000, 24000, 16000,
765            8000, 0, -8000, -16000, -24000, -30000, -32000, -32000,
766            32000, 32000, 32000, 32000, -32000, -32000, -32000, -32000,
767            32000, 32000, 32000, 32000, -32000, -32000, -32000, -32000,
768            -32, -16, -8, 0, 8, 16, 32, 16,
769            8, 0, -8, -16, -32, -16, -8, 0,
770            4, 8, 12, 16, 0, 4, 8, 12,
771            16, 12, 8, 4, 0, 16, 8, 4,
772        ], &mut state, &mut encoded_buf);
773        assert_eq!(encoded_buf, [ 0x00, 0x00,
774            0x77, 0x77, 0x77, 0x77, 0xf3, 0xae, 0xab, 0x88,
775            0x77, 0x02, 0x9f, 0x08, 0x17, 0x80, 0x9f, 0x08,
776            0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
777            0x08, 0x08, 0x08, 0x88, 0x00, 0x88, 0x00, 0x88,
778        ]);
779        assert_eq!(state, AdpcmImaState { predictor: -197, step_index: 56 });
780    }
781
782    #[test]
783    fn test_encode_adpcm_ms() {
784        // Windows 10 acmStreamConvert() has been tested to return the same values
785
786        // one channel
787        let mut states = [ AdpcmImaState::new() ];
788        let mut buf = [0u8; 16];
789        assert!(encode_adpcm_ima_ms(&[
790            10, 10, 20, 50, 80, 100, 500, 1000, 1500, 2000,
791            1500, 800, 500, 300, 100, -100, -300, -500, -800, -1400,
792            -3000, -6000, -9000, -12000, -15000
793        ], &mut states, &mut buf).is_ok());
794        assert_eq!(buf, [
795            10, 0, 0, 0, 96, 87, 113, 119, 7, 155, 153, 169, 185, 254, 223, 187
796        ]);
797
798        // two channels
799        let mut states = [ AdpcmImaState::new(), AdpcmImaState::new() ];
800        let mut buf = [0u8; 16];
801        assert!(encode_adpcm_ima_ms(&[
802            10, 18, 30, 38, 50, 57, 100, 106, 400, 410,
803            300, 310, 100, 110, 40, 46, 20, 26
804        ], &mut states, &mut buf).is_ok());
805        assert_eq!(buf, [
806            10, 0, 0, 0, 18, 0, 0, 0, 119, 117, 228, 9, 119, 117, 228, 9
807        ]);
808
809        // zero and three channels fail
810        let mut states = [];
811        let mut buf = [0u8; 16];
812        assert!(matches!(encode_adpcm_ima_ms(&[
813            10, 18, 30, 38, 50, 57, 100, 106, 400, 410, 300, 310, 100, 110, 40, 46, 20, 26
814        ], &mut states, &mut buf), Err(Error::InvalidChannels)));
815
816        let mut states = [ AdpcmImaState::new(), AdpcmImaState::new(), AdpcmImaState::new() ];
817        let mut buf = [0u8; 16];
818        assert!(matches!(encode_adpcm_ima_ms(&[
819            10, 18, 30, 38, 50, 57, 100, 106, 400, 410, 300, 310, 100, 110, 40, 46, 20, 26
820        ], &mut states, &mut buf), Err(Error::InvalidChannels)));
821
822        // invalid number of samples
823        let mut states = [ AdpcmImaState::new() ];
824        let mut buf = [0u8; 5];
825        assert!(matches!(encode_adpcm_ima_ms(&[
826            10, 18
827        ], &mut states, &mut buf), Err(Error::InvalidBufferSize)));
828
829        let mut states = [ AdpcmImaState::new(), AdpcmImaState::new() ];
830        let mut buf = [0u8; 16];
831        assert!(matches!(encode_adpcm_ima_ms(&[
832            10, 18, 20
833        ], &mut states, &mut buf), Err(Error::InvalidBufferSize)));
834
835        // invalid out_buf length
836        let mut states = [ AdpcmImaState::new() ];
837        let mut buf = [0u8; 15];
838        assert!(matches!(encode_adpcm_ima_ms(&[
839            10, 10, 20, 50, 80, 100, 500, 1000, 1500, 2000,
840            1500, 800, 500, 300, 100, -100, -300, -500, -800, -1400,
841            -3000, -6000, -9000, -12000, -15000
842        ], &mut states, &mut buf), Err(Error::InvalidBufferSize)));
843
844        // 1 channel 2041 samples can be encoded to buf size 1024
845        let mut states = [ AdpcmImaState::new() ];
846        let mut buf = [0u8; 1024];
847        assert!(encode_adpcm_ima_ms(&[0i16; 2041], &mut states, &mut buf).is_ok());
848
849        // 2 channels 4082 samples can be encoded to buf size 2048
850        let mut states = [ AdpcmImaState::new(), AdpcmImaState::new() ];
851        let mut buf = [0u8; 2048];
852        assert!(encode_adpcm_ima_ms(&[0i16; 4082], &mut states, &mut buf).is_ok());
853    }
854
855    #[test]
856    fn test_encode_adpcm_ms_with_different_buf_sizes() {
857        let sample_area = [0i16; 8192];
858        let mut buf_area = [0u8; 4096];
859        // one channel
860        for buf_len in 0..=1025 {
861            let mut buf = &mut buf_area[0..buf_len];
862            let sample_len = 2 * buf.len().max(4) - 7 * 1;
863            let samples = &sample_area[0..sample_len];
864            let mut states = [ AdpcmImaState::new() ];
865            if buf_len >= 4 {
866                assert!(encode_adpcm_ima_ms(&samples, &mut states, &mut buf).is_ok());
867            } else {
868                assert!(matches!(encode_adpcm_ima_ms(&samples, &mut states, &mut buf),
869                    Err(Error::InvalidBufferSize)));
870            }
871        }
872        // two channels
873        for buf_len in 0..=2049 {
874            let mut buf = &mut buf_area[0..buf_len];
875            let sample_len = 2 * buf.len().max(7) - 7 * 2;
876            let samples = &sample_area[0..sample_len];
877            let mut states = [ AdpcmImaState::new(), AdpcmImaState::new() ];
878            if buf_len >= 8 && buf_len % 8 == 0 {
879                assert!(encode_adpcm_ima_ms(&samples, &mut states, &mut buf).is_ok());
880            } else {
881                assert!(matches!(encode_adpcm_ima_ms(&samples, &mut states, &mut buf),
882                    Err(Error::InvalidBufferSize)));
883            }
884        }
885    }
886
887}