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() % 8 != 0)) {
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)]
206#[inline(always)]
207pub fn encode_adpcm_ima(sample_value: i16, state: &mut AdpcmImaState) -> u8 {
208 state.step_index = state.step_index.min(88); 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 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 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 temp_step_size >>= 1;
239 if diff >= temp_step_size {
240 nibble |= 1;
241 predictor_diff += step_size >> 2;
242 }
243
244 let mut predictor = i32::from(state.predictor);
246 if (nibble & 8) == 8 {
247 predictor -= predictor_diff;
248 } else {
249 predictor += predictor_diff;
250 }
251 #[allow(clippy::cast_possible_truncation)] {
254 state.predictor = predictor.clamp(-32768, 32767) as i16;
255 }
256 state.step_index = state.step_index
258 .saturating_add_signed(IMA_INDEX_TABLE[usize::from(nibble)])
259 .min(88);
260 nibble
262}
263
264#[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 #[allow(clippy::cast_sign_loss)] {
280 out_buf[0] = (state.predictor >> 8) as u8;
281 out_buf[1] = (state.predictor & 0x80) as u8 | state.step_index;
282 }
283 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
294pub 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 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 if out_buf.len() > 0xffff {
329 return Err(crate::Error::InvalidBufferSize);
330 }
331 if ((samples.len() - states.len()) / 2) + states.len()*4 != out_buf.len() {
333 return Err(crate::Error::InvalidBufferSize);
334 }
335 for ch in 0..channels {
337 states[ch].predictor = samples[ch];
338 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 let mut samples = [0i16; 25];
617 assert!(matches!(decode_adpcm_ima_ms(&[ 0x38, 0xB1, 0x47
618 ], false, &mut samples), Err(Error::InvalidBufferSize)));
619
620 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 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 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 let mut samples = [0i16; 2041];
647 assert!(decode_adpcm_ima_ms(&[0u8; 1024], false, &mut samples).is_ok());
648
649 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}