1use crate::common::complex::Scaler;
2
3pub fn decode(lsb_mode: bool, residual_bits: &[bool], spec_lines: &mut [Scaler]) {
14 if !lsb_mode {
15 let mut bits = residual_bits.iter();
16
17 for spec_line in spec_lines.iter_mut() {
18 if *spec_line != 0.0 {
19 match bits.next() {
20 Some(true) => {
21 if *spec_line > 0.0 {
22 *spec_line += 0.3125
23 } else {
24 *spec_line += 0.1875
25 }
26 }
27 Some(false) => {
28 if *spec_line > 0.0 {
29 *spec_line -= 0.1875
30 } else {
31 *spec_line -= 0.3125
32 }
33 }
34 None => break,
35 }
36 }
37 }
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 extern crate std;
44 use super::*;
45
46 #[test]
47 fn residual_spectrum_decode() {
48 let lsb_mode = false;
49 let residual_bits = [
50 false, true, true, true, false, false, false, true, false, false, true, true, true, false, false, false,
51 true, true, true, false, true, false, true, true, false, false, true, true, false, true, true, false, true,
52 true, true, false, true, false, true, true, false, false, true, true, true,
53 ];
54 let mut x_hat = [
55 -9.0, 32.0, 65.0, 40.0, -4.0, -48.0, -36.0, 2.0, 21.0, -6.0, 27.0, 9.0, -9.0, -26.0, 9.0, -4.0, -1.0, 12.0,
56 -8.0, -2.0, 23.0, -33.0, -10.0, 3.0, -15.0, -3.0, 5.0, 17.0, -1.0, 12.0, 27.0, -4.0, 8.0, 2.0, 10.0, -7.0,
57 8.0, -6.0, 3.0, -22.0, 24.0, -6.0, -1.0, 2.0, 0.0, 1.0, -8.0, 3.0, -2.0, 0.0, 0.0, 2.0, -6.0, -2.0, -4.0,
58 -3.0, 0.0, 1.0, 0.0, -7.0, -4.0, -11.0, -7.0, -6.0, 0.0, 3.0, 10.0, 2.0, 9.0, 3.0, 7.0, -2.0, 2.0, -2.0,
59 -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.0, -1.0, -1.0, -1.0, 2.0, 1.0, 3.0, 3.0, 1.0, -2.0, -2.0, 1.0, 5.0,
60 2.0, -2.0, -5.0, -4.0, -2.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -3.0, -1.0, 1.0, 3.0,
61 0.0, 0.0, 1.0, 2.0, -1.0, -1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 0.0, -2.0, -3.0, 0.0, 3.0, 2.0, 0.0, 0.0, 0.0,
62 0.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
63 2.0, 0.0, -1.0, -1.0, 0.0, 2.0, 0.0, 2.0, 0.0, 0.0, -2.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 2.0, 0.0,
64 -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, -1.0,
65 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 2.0,
66 -1.0, 0.0, 2.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 2.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0,
67 -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 2.0, -2.0,
68 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, -2.0, -1.0, -1.0, 0.0, 1.0, -1.0,
69 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, -1.0,
70 -1.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
71 -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0,
72 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
73 -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0,
74 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
75 -1.0, 0.0, 0.0, 1.0, 1.0,
76 ];
77
78 decode(lsb_mode, &residual_bits, &mut x_hat);
79
80 let x_hat_expected = [
81 -9.3125, 32.3125, 65.3125, 40.3125, -4.3125, -48.3125, -36.3125, 2.3125, 20.8125, -6.3125, 27.3125, 9.3125,
82 -8.8125, -26.3125, 8.8125, -4.3125, -0.8125, 12.3125, -7.8125, -2.3125, 23.3125, -33.3125, -9.8125, 3.3125,
83 -15.3125, -3.3125, 5.3125, 17.3125, -1.3125, 12.3125, 27.3125, -4.3125, 8.3125, 2.3125, 10.3125, -7.3125,
84 8.3125, -6.3125, 3.3125, -21.8125, 23.8125, -6.3125, -0.8125, 2.3125, 0.0, 1.3125, -8.0, 3.0, -2.0, 0.0,
85 0.0, 2.0, -6.0, -2.0, -4.0, -3.0, 0.0, 1.0, 0.0, -7.0, -4.0, -11.0, -7.0, -6.0, 0.0, 3.0, 10.0, 2.0, 9.0,
86 3.0, 7.0, -2.0, 2.0, -2.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.0, -1.0, -1.0, -1.0, 2.0, 1.0, 3.0, 3.0,
87 1.0, -2.0, -2.0, 1.0, 5.0, 2.0, -2.0, -5.0, -4.0, -2.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0,
88 -1.0, -3.0, -1.0, 1.0, 3.0, 0.0, 0.0, 1.0, 2.0, -1.0, -1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 0.0, -2.0, -3.0, 0.0,
89 3.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0,
90 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, -1.0, -1.0, 0.0, 2.0, 0.0, 2.0, 0.0, 0.0, -2.0, -1.0, 0.0, 1.0, 0.0, -1.0,
91 0.0, 1.0, 2.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0,
92 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0,
93 0.0, -1.0, 1.0, 2.0, -1.0, 0.0, 2.0, 0.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 2.0, -1.0, -1.0, 0.0, 0.0,
94 0.0, 0.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0,
95 0.0, 1.0, 2.0, -2.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, -2.0, -1.0,
96 -1.0, 0.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0,
97 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 1.0,
98 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0,
99 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
100 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
101 -1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0,
102 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0,
103 ];
104
105 assert_eq!(x_hat, x_hat_expected);
106 }
107}