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