Skip to main content

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