Skip to main content

ezk_g722/libg722/
decoder.rs

1//
2// SpanDSP - a series of DSP components for telephony
3//
4// g722_decode.c - The ITU G.722 codec, decode part.
5//
6// Written by Steve Underwood <steveu@coppice.org>
7//
8// Copyright (C) 2005 Steve Underwood
9//
10//  Despite my general liking of the GPL, I place my own contributions
11//  to this code in the public domain for the benefit of all mankind -
12//  even the slimy ones who might try to proprietize my work and use it
13//  to my detriment.
14//
15// Based in part on a single channel G.722 codec which is:
16//
17// Copyright (c) CMU 1993
18// Computer Science, Speech Group
19// Chengxiang Lu and Alex Hauptmann
20//
21// The Carnegie Mellon ADPCM program is Copyright (c) 1993 by Carnegie Mellon
22// University. Use of this program, for any research or commercial purpose, is
23// completely unrestricted. If you make use of or redistribute this material,
24// we would appreciate acknowlegement of its origin.
25//
26
27use super::{block4, saturate, Bitrate, G722Band};
28
29pub struct Decoder {
30    itu_test_mode: bool,
31    packed: bool,
32    eight_k: bool,
33    bits_per_sample: i32,
34    x: [i32; 24],
35    band: [G722Band; 2],
36    in_buffer: u32,
37    in_bits: i32,
38}
39
40impl Decoder {
41    pub fn new(rate: Bitrate, packed: bool, eight_k: bool) -> Self {
42        Self {
43            itu_test_mode: false,
44            packed,
45            eight_k,
46            bits_per_sample: rate.bits_per_sample(),
47            x: Default::default(),
48            band: Default::default(),
49            in_buffer: 0,
50            in_bits: 0,
51        }
52    }
53
54    pub fn decode(&mut self, g722_data: &[u8]) -> Vec<i16> {
55        g722_decode(self, g722_data)
56    }
57}
58
59fn g722_decode(s: &mut Decoder, g722_data: &[u8]) -> Vec<i16> {
60    static WL: [i32; 8] = [-60, -30, 58, 172, 334, 538, 1198, 3042];
61    static RL42: [i32; 16] = [0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0];
62    static ILB: [i32; 32] = [
63        2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, 2435, 2489, 2543, 2599, 2656, 2714, 2774,
64        2834, 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, 3444, 3520, 3597, 3676, 3756, 3838,
65        3922, 4008,
66    ];
67    static WH: [i32; 3] = [0, -214, 798];
68    static RH2: [i32; 4] = [2, 1, 2, 1];
69    static QM2: [i32; 4] = [-7408, -1616, 7408, 1616];
70    static QM4: [i32; 16] = [
71        0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, 20456, 12896, 8968, 6288, 4240, 2584,
72        1200, 0,
73    ];
74    static QM5: [i32; 32] = [
75        -280, -280, -23352, -17560, -14120, -11664, -9752, -8184, -6864, -5712, -4696, -3784,
76        -2960, -2208, -1520, -880, 23352, 17560, 14120, 11664, 9752, 8184, 6864, 5712, 4696, 3784,
77        2960, 2208, 1520, 880, 280, -280,
78    ];
79    static QM6: [i32; 64] = [
80        -136, -136, -136, -136, -24808, -21904, -19008, -16704, -14984, -13512, -12280, -11192,
81        -10232, -9360, -8576, -7856, -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, -3168,
82        -2776, -2400, -2032, -1688, -1360, -1040, -728, 24808, 21904, 19008, 16704, 14984, 13512,
83        12280, 11192, 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, 4944, 4464, 4008, 3576,
84        3168, 2776, 2400, 2032, 1688, 1360, 1040, 728, 432, 136, -432, -136,
85    ];
86    static QMF_COEFFS: [i32; 12] = [3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11];
87
88    let mut dlowt: i32;
89    let mut rlow: i32;
90    let mut ihigh: i32;
91    let mut dhigh: i32;
92    let mut rhigh: i32;
93    let mut xout1: i32;
94    let mut xout2: i32;
95    let mut wd1: i32;
96    let mut wd2: i32;
97    let mut wd3: i32;
98    let mut code: i32;
99    let mut i: usize;
100    let mut j: usize;
101
102    let mut out = vec![];
103
104    rhigh = 0;
105    j = 0;
106    while j < g722_data.len() {
107        if s.packed {
108            /* Unpack the code bits */
109            if s.in_bits < s.bits_per_sample {
110                s.in_buffer |= (g722_data[j] as u32) << s.in_bits;
111                j += 1;
112                s.in_bits += 8;
113            }
114            code = (s.in_buffer & ((1 << s.bits_per_sample) - 1) as u32) as i32;
115            s.in_buffer >>= s.bits_per_sample;
116            s.in_bits -= s.bits_per_sample;
117        } else {
118            code = g722_data[j] as i32;
119            j += 1;
120        }
121
122        match s.bits_per_sample {
123            7 => {
124                wd1 = code & 0x1f;
125                ihigh = code >> 5 & 0x3;
126                wd2 = QM5[wd1 as usize];
127                wd1 >>= 1;
128            }
129            6 => {
130                wd1 = code & 0xf;
131                ihigh = code >> 4 & 0x3;
132                wd2 = QM4[wd1 as usize];
133            }
134            _ => {
135                wd1 = code & 0x3f;
136                ihigh = code >> 6 & 0x3;
137                wd2 = QM6[wd1 as usize];
138                wd1 >>= 2;
139            }
140        }
141
142        // Block 5L, LOW BAND INVQBL
143        wd2 = (s.band[0].det * wd2) >> 15;
144
145        // Block 5L, RECONS
146        rlow = s.band[0].s + wd2;
147
148        // Block 6L, LIMIT
149        rlow = rlow.clamp(-16384, 16383);
150
151        // Block 2L, INVQAL
152        wd2 = QM4[wd1 as usize];
153        dlowt = (s.band[0].det * wd2) >> 15;
154
155        // Block 3L, LOGSCL
156        wd2 = RL42[wd1 as usize];
157        wd1 = (s.band[0].nb * 127) >> 7;
158        wd1 += WL[wd2 as usize];
159        wd1 = wd1.clamp(0, 18432);
160        s.band[0].nb = wd1;
161
162        // Block 3L, SCALEL
163        wd1 = s.band[0].nb >> 6 & 31;
164        wd2 = 8 - (s.band[0].nb >> 11);
165        wd3 = if wd2 < 0 {
166            ILB[wd1 as usize] << -wd2
167        } else {
168            ILB[wd1 as usize] >> wd2
169        };
170        s.band[0].det = wd3 << 2;
171
172        block4(&mut s.band[0], dlowt);
173
174        if !s.eight_k {
175            // Block 2H, INVQAH
176            wd2 = QM2[ihigh as usize];
177            dhigh = (s.band[1].det * wd2) >> 15;
178
179            // Block 5H, RECONS
180            rhigh = dhigh + s.band[1].s;
181
182            // Block 6H, LIMIT
183            rhigh = rhigh.clamp(-(16384), 16383);
184
185            // Block 2H, INVQAH
186            wd2 = RH2[ihigh as usize];
187            wd1 = (s.band[1].nb * 127) >> 7;
188            wd1 += WH[wd2 as usize];
189            wd1 = wd1.clamp(0, 22528);
190            s.band[1].nb = wd1;
191
192            // Block 3H, SCALEH
193            wd1 = s.band[1].nb >> 6 & 31;
194            wd2 = 10 - (s.band[1].nb >> 11);
195            wd3 = if wd2 < 0 {
196                ILB[wd1 as usize] << -wd2
197            } else {
198                ILB[wd1 as usize] >> wd2
199            };
200            s.band[1].det = wd3 << 2;
201
202            block4(&mut s.band[1], dhigh);
203        }
204
205        if s.itu_test_mode {
206            out.push((rlow << 1) as i16);
207            out.push((rhigh << 1) as i16);
208        } else if s.eight_k {
209            out.push((rlow << 1) as i16);
210        } else {
211            // Apply the receive QMF
212            for i in 0..22 {
213                s.x[i] = s.x[i + 2];
214            }
215            s.x[22] = rlow + rhigh;
216            s.x[23] = rlow - rhigh;
217
218            xout1 = 0;
219            xout2 = 0;
220            i = 0;
221            while i < 12 {
222                xout2 += s.x[2 * i] * QMF_COEFFS[i];
223                xout1 += s.x[2 * i + 1] * QMF_COEFFS[11 - i];
224                i += 1;
225            }
226
227            out.push(saturate(xout1 >> 11) as i16);
228            out.push(saturate(xout2 >> 11) as i16);
229        }
230    }
231
232    out
233}