1const LOG_Q15_ACCURACY: i32 = 15;
2const LOG_Q15_INTEGER_PART: i32 = 4;
3const LOQ_Q15_THRESHOLD: u32 = 1u32 << LOG_Q15_ACCURACY;
4const LOQ_Q15_Q16_HALF: u32 = LOQ_Q15_THRESHOLD;
5const LOG_Q15_INVLOG2EXP: i32 = 0x58b9; const LOG_Q31_ACCURACY: i32 = 31;
8const LOG_Q31_INTEGER_PART: i32 = 5;
9const LOQ_Q31_THRESHOLD: u64 = 1u64 << LOG_Q31_ACCURACY;
10const LOQ_Q31_Q32_HALF: u64 = LOQ_Q31_THRESHOLD;
11const LOG_Q31_INVLOG2EXP: i64 = 0x58b90bfb; fn log_i16(x: i16) -> i16 {
14 let src = x as u16 as u32;
15
16 let c = src.leading_zeros() as i32 - 16;
17 let normalization = c;
18
19 let mut inc: u32 = LOQ_Q15_Q16_HALF >> (LOG_Q15_INTEGER_PART + 1);
20
21 let mut xn = src;
22 if (c - 1) < 0 {
23 xn >>= 1 - c;
24 } else {
25 xn <<= c - 1;
26 }
27
28 let mut y: u32 = 0;
29
30 for _ in 0..LOG_Q15_ACCURACY {
31 xn = ((xn as i32 * xn as i32) >> (LOG_Q15_ACCURACY - 1)) as u32;
32
33 if xn >= LOQ_Q15_THRESHOLD {
34 y = y.wrapping_add(inc);
35 xn >>= 1;
36 }
37 inc >>= 1;
38 }
39
40 let tmp = y as i32 - (normalization << (LOG_Q15_ACCURACY - LOG_Q15_INTEGER_PART));
41 (((tmp as i64 * LOG_Q15_INVLOG2EXP as i64) >> 15) as i32) as i16
42}
43
44pub fn vlog_i16(input: &[i16], output: &mut [i16]) {
45 assert_eq!(
46 input.len(),
47 output.len(),
48 "input and output lengths must match"
49 );
50 for (x, y) in input.iter().zip(output.iter_mut()) {
51 *y = log_i16(*x);
52 }
53}
54
55pub fn vlog_i16_in_place(input: &mut [i16]) {
56 for x in input.iter_mut() {
57 *x = log_i16(*x);
58 }
59}
60
61fn log_i32(x: i32) -> i32 {
62 let src = x as u32;
63
64 let c = src.leading_zeros() as i32;
65 let normalization = c;
66
67 let mut inc: u64 = LOQ_Q31_Q32_HALF >> (LOG_Q31_INTEGER_PART + 1);
68
69 let mut xn = src as u64;
70 if (c - 1) < 0 {
71 xn >>= 1 - c;
72 } else {
73 xn <<= c - 1;
74 }
75
76 let mut y: u64 = 0;
77
78 for _ in 0..LOG_Q31_ACCURACY {
79 xn = ((xn * xn) >> (LOG_Q31_ACCURACY - 1)) as u64;
80
81 if xn >= LOQ_Q31_THRESHOLD {
82 y = y.wrapping_add(inc);
83 xn >>= 1;
84 }
85 inc >>= 1;
86 }
87
88 let tmp = y as i64 - ((normalization as i64) << (LOG_Q31_ACCURACY - LOG_Q31_INTEGER_PART));
89 ((tmp * LOG_Q31_INVLOG2EXP) >> 31) as i32
90}
91
92pub fn vlog_i32(input: &[i32], output: &mut [i32]) {
93 assert_eq!(
94 input.len(),
95 output.len(),
96 "input and output lengths must match"
97 );
98 for (x, y) in input.iter().zip(output.iter_mut()) {
99 *y = log_i32(*x);
100 }
101}
102
103pub fn vlog_i32_in_place(input: &mut [i32]) {
104 for x in input.iter_mut() {
105 *x = log_i32(*x);
106 }
107}