1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 /*
12 * decode_B.c
13 *
14 * This file contains definition of funtions for decoding.
15 * Decoding of lower-band, including normal-decoding and RCU decoding.
16 * Decoding of upper-band, including 8-12 kHz, when the bandwidth is
17 * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
18 *
19 */
20
21
22 #include "codec.h"
23 #include "entropy_coding.h"
24 #include "pitch_estimator.h"
25 #include "bandwidth_estimator.h"
26 #include "structs.h"
27 #include "settings.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33
34 /*
35 * function to decode the bitstream
36 * returns the total number of bytes in the stream
37 */
WebRtcIsac_DecodeLb(const TransformTables * transform_tables,float * signal_out,ISACLBDecStruct * ISACdecLB_obj,int16_t * current_framesamples,int16_t isRCUPayload)38 int WebRtcIsac_DecodeLb(const TransformTables* transform_tables,
39 float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
40 int16_t* current_framesamples,
41 int16_t isRCUPayload) {
42 int k;
43 int len, err;
44 int16_t bandwidthInd;
45
46 float LP_dec_float[FRAMESAMPLES_HALF];
47 float HP_dec_float[FRAMESAMPLES_HALF];
48
49 double LPw[FRAMESAMPLES_HALF];
50 double HPw[FRAMESAMPLES_HALF];
51 double LPw_pf[FRAMESAMPLES_HALF];
52
53 double lo_filt_coef[(ORDERLO + 1)*SUBFRAMES];
54 double hi_filt_coef[(ORDERHI + 1)*SUBFRAMES];
55
56 double real_f[FRAMESAMPLES_HALF];
57 double imag_f[FRAMESAMPLES_HALF];
58
59 double PitchLags[4];
60 double PitchGains[4];
61 double AvgPitchGain;
62 int16_t PitchGains_Q12[4];
63 int16_t AvgPitchGain_Q12;
64
65 float gain;
66
67 int frame_nb; /* counter */
68 int frame_mode; /* 0 30ms, 1 for 60ms */
69 /* Processed_samples: 480 (30, 60 ms). Cannot take other values. */
70
71 WebRtcIsac_ResetBitstream(&(ISACdecLB_obj->bitstr_obj));
72
73 len = 0;
74
75 /* Decode framelength and BW estimation - not used,
76 only for stream pointer*/
77 err = WebRtcIsac_DecodeFrameLen(&ISACdecLB_obj->bitstr_obj,
78 current_framesamples);
79 if (err < 0) {
80 return err;
81 }
82
83 /* Frame_mode:
84 * 0: indicates 30 ms frame (480 samples)
85 * 1: indicates 60 ms frame (960 samples) */
86 frame_mode = *current_framesamples / MAX_FRAMESAMPLES;
87
88 err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd);
89 if (err < 0) {
90 return err;
91 }
92
93 /* One loop if it's one frame (20 or 30ms), 2 loops if 2 frames
94 bundled together (60ms). */
95 for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
96 /* Decode & de-quantize pitch parameters */
97 err = WebRtcIsac_DecodePitchGain(&ISACdecLB_obj->bitstr_obj,
98 PitchGains_Q12);
99 if (err < 0) {
100 return err;
101 }
102
103 err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, PitchGains_Q12,
104 PitchLags);
105 if (err < 0) {
106 return err;
107 }
108
109 AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
110 PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
111
112 /* Decode & de-quantize filter coefficients. */
113 err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, lo_filt_coef,
114 hi_filt_coef);
115 if (err < 0) {
116 return err;
117 }
118 /* Decode & de-quantize spectrum. */
119 len = WebRtcIsac_DecodeSpec(&ISACdecLB_obj->bitstr_obj, AvgPitchGain_Q12,
120 kIsacLowerBand, real_f, imag_f);
121 if (len < 0) {
122 return len;
123 }
124
125 /* Inverse transform. */
126 WebRtcIsac_Spec2time(transform_tables, real_f, imag_f, LPw, HPw,
127 &ISACdecLB_obj->fftstr_obj);
128
129 /* Convert PitchGains back to float for pitchfilter_post */
130 for (k = 0; k < 4; k++) {
131 PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
132 }
133 if (isRCUPayload) {
134 for (k = 0; k < 240; k++) {
135 LPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
136 HPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
137 }
138 }
139
140 /* Inverse pitch filter. */
141 WebRtcIsac_PitchfilterPost(LPw, LPw_pf, &ISACdecLB_obj->pitchfiltstr_obj,
142 PitchLags, PitchGains);
143 /* Convert AvgPitchGain back to float for computation of gain. */
144 AvgPitchGain = ((float)AvgPitchGain_Q12) / 4096;
145 gain = 1.0f - 0.45f * (float)AvgPitchGain;
146
147 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
148 /* Reduce gain to compensate for pitch enhancer. */
149 LPw_pf[k] *= gain;
150 }
151
152 if (isRCUPayload) {
153 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
154 /* Compensation for transcoding gain changes. */
155 LPw_pf[k] *= RCU_TRANSCODING_SCALE;
156 HPw[k] *= RCU_TRANSCODING_SCALE;
157 }
158 }
159 /* Perceptual post-filtering (using normalized lattice filter). */
160 WebRtcIsac_NormLatticeFilterAr(
161 ORDERLO, ISACdecLB_obj->maskfiltstr_obj.PostStateLoF,
162 (ISACdecLB_obj->maskfiltstr_obj).PostStateLoG, LPw_pf, lo_filt_coef,
163 LP_dec_float);
164 WebRtcIsac_NormLatticeFilterAr(
165 ORDERHI, ISACdecLB_obj->maskfiltstr_obj.PostStateHiF,
166 (ISACdecLB_obj->maskfiltstr_obj).PostStateHiG, HPw, hi_filt_coef,
167 HP_dec_float);
168
169 /* Recombine the 2 bands. */
170 WebRtcIsac_FilterAndCombineFloat(LP_dec_float, HP_dec_float,
171 signal_out + frame_nb * FRAMESAMPLES,
172 &ISACdecLB_obj->postfiltbankstr_obj);
173 }
174 return len;
175 }
176
177
178 /*
179 * This decode function is called when the codec is operating in 16 kHz
180 * bandwidth to decode the upperband, i.e. 8-16 kHz.
181 *
182 * Contrary to lower-band, the upper-band (8-16 kHz) is not split in
183 * frequency, but split to 12 sub-frames, i.e. twice as lower-band.
184 */
WebRtcIsac_DecodeUb16(const TransformTables * transform_tables,float * signal_out,ISACUBDecStruct * ISACdecUB_obj,int16_t isRCUPayload)185 int WebRtcIsac_DecodeUb16(const TransformTables* transform_tables,
186 float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
187 int16_t isRCUPayload) {
188 int len, err;
189
190 double halfFrameFirst[FRAMESAMPLES_HALF];
191 double halfFrameSecond[FRAMESAMPLES_HALF];
192
193 double percepFilterParam[(UB_LPC_ORDER + 1) * (SUBFRAMES << 1) +
194 (UB_LPC_ORDER + 1)];
195
196 double real_f[FRAMESAMPLES_HALF];
197 double imag_f[FRAMESAMPLES_HALF];
198 const int16_t kAveragePitchGain = 0; /* No pitch-gain for upper-band. */
199 len = 0;
200
201 /* Decode & de-quantize filter coefficients. */
202 memset(percepFilterParam, 0, sizeof(percepFilterParam));
203 err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
204 percepFilterParam, isac16kHz);
205 if (err < 0) {
206 return err;
207 }
208
209 /* Decode & de-quantize spectrum. */
210 len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain,
211 kIsacUpperBand16, real_f, imag_f);
212 if (len < 0) {
213 return len;
214 }
215 if (isRCUPayload) {
216 int n;
217 for (n = 0; n < 240; n++) {
218 real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
219 imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
220 }
221 }
222 /* Inverse transform. */
223 WebRtcIsac_Spec2time(transform_tables,
224 real_f, imag_f, halfFrameFirst, halfFrameSecond,
225 &ISACdecUB_obj->fftstr_obj);
226
227 /* Perceptual post-filtering (using normalized lattice filter). */
228 WebRtcIsac_NormLatticeFilterAr(
229 UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
230 (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameFirst,
231 &percepFilterParam[(UB_LPC_ORDER + 1)], signal_out);
232
233 WebRtcIsac_NormLatticeFilterAr(
234 UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
235 (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameSecond,
236 &percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER + 1)],
237 &signal_out[FRAMESAMPLES_HALF]);
238
239 return len;
240 }
241
242 /*
243 * This decode function is called when the codec operates at 0-12 kHz
244 * bandwidth to decode the upperband, i.e. 8-12 kHz.
245 *
246 * At the encoder the upper-band is split into two band, 8-12 kHz & 12-16
247 * kHz, and only 8-12 kHz is encoded. At the decoder, 8-12 kHz band is
248 * reconstructed and 12-16 kHz replaced with zeros. Then two bands
249 * are combined, to reconstruct the upperband 8-16 kHz.
250 */
WebRtcIsac_DecodeUb12(const TransformTables * transform_tables,float * signal_out,ISACUBDecStruct * ISACdecUB_obj,int16_t isRCUPayload)251 int WebRtcIsac_DecodeUb12(const TransformTables* transform_tables,
252 float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
253 int16_t isRCUPayload) {
254 int len, err;
255
256 float LP_dec_float[FRAMESAMPLES_HALF];
257 float HP_dec_float[FRAMESAMPLES_HALF];
258
259 double LPw[FRAMESAMPLES_HALF];
260 double HPw[FRAMESAMPLES_HALF];
261
262 double percepFilterParam[(UB_LPC_ORDER + 1)*SUBFRAMES];
263
264 double real_f[FRAMESAMPLES_HALF];
265 double imag_f[FRAMESAMPLES_HALF];
266 const int16_t kAveragePitchGain = 0; /* No pitch-gain for upper-band. */
267 len = 0;
268
269 /* Decode & dequantize filter coefficients. */
270 err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
271 percepFilterParam, isac12kHz);
272 if (err < 0) {
273 return err;
274 }
275
276 /* Decode & de-quantize spectrum. */
277 len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain,
278 kIsacUpperBand12, real_f, imag_f);
279 if (len < 0) {
280 return len;
281 }
282
283 if (isRCUPayload) {
284 int n;
285 for (n = 0; n < 240; n++) {
286 real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
287 imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
288 }
289 }
290 /* Inverse transform. */
291 WebRtcIsac_Spec2time(transform_tables,
292 real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj);
293 /* perceptual post-filtering (using normalized lattice filter) */
294 WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
295 ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
296 (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG,
297 LPw, percepFilterParam, LP_dec_float);
298 /* Zero for 12-16 kHz. */
299 memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF));
300 /* Recombine the 2 bands. */
301 WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out,
302 &ISACdecUB_obj->postfiltbankstr_obj);
303 return len;
304 }
305