1
2#[cfg(feature = "internal-no-panic")]
3use no_panic::no_panic;
4
5use crate::Error;
6
7#[derive(Debug, Clone, PartialEq)]
11pub struct AdpcmImaState {
12 pub predictor: i16,
13 pub step_index: u8,
14}
15
16impl AdpcmImaState {
17 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#[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; state.step_index = state.step_index.min(88); 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 #[allow(clippy::cast_possible_truncation)] {
77 state.predictor = predictor.clamp(-32768, 32767) as i16;
78 }
79 state.step_index = state.step_index
81 .saturating_add_signed(IMA_INDEX_TABLE[usize::from(nibble)])
82 .min(88);
83 state.predictor
85}
86
87#[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 let predictor = i16::from_be_bytes([ buf[0], buf[1] & 0b1000_0000 ]);
102 let step_index = (buf[1] & 0b0111_1111).min(88);
104 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 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
127pub 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 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 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 for ch in 0..channels {
171 states[ch].predictor = i16::from_le_bytes([ buf[ch*4], buf[ch*4+1] ]);
172 states[ch].step_index = buf[ch*4+2].min(88);
177 out_samples[ch] = states[ch].predictor;
178 }
179 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#[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); 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 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 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 temp_step_size >>= 1;
241 if diff >= temp_step_size {
242 nibble |= 1;
243 predictor_diff += step_size >> 2;
244 }
245
246 let mut predictor = i32::from(state.predictor);
248 if (nibble & 8) == 8 {
249 predictor -= predictor_diff;
250 } else {
251 predictor += predictor_diff;
252 }
253 #[allow(clippy::cast_possible_truncation)] {
256 state.predictor = predictor.clamp(-32768, 32767) as i16;
257 }
258 state.step_index = state.step_index
260 .saturating_add_signed(IMA_INDEX_TABLE[usize::from(nibble)])
261 .min(88);
262 nibble
264}
265
266#[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 #[allow(clippy::cast_sign_loss)] {
282 out_buf[0] = (state.predictor >> 8) as u8;
283 out_buf[1] = (state.predictor & 0x80) as u8 | state.step_index;
284 }
285 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
296pub 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 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 if out_buf.len() > 0xffff {
331 return Err(crate::Error::InvalidBufferSize);
332 }
333 if ((samples.len() - states.len()) / 2) + states.len()*4 != out_buf.len() {
335 return Err(crate::Error::InvalidBufferSize);
336 }
337 for ch in 0..channels {
339 states[ch].predictor = samples[ch];
340 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 let mut samples = [0i16; 25];
619 assert!(matches!(decode_adpcm_ima_ms(&[ 0x38, 0xB1, 0x47
620 ], false, &mut samples), Err(Error::InvalidBufferSize)));
621
622 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 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 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 let mut samples = [0i16; 2041];
649 assert!(decode_adpcm_ima_ms(&[0u8; 1024], false, &mut samples).is_ok());
650
651 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}