1/*
2 *  Copyright (c) 2011 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.c
13 *
14 * This C file contains the internal decoding function.
15 *
16 */
17
18#include <string.h>
19
20#include "bandwidth_estimator.h"
21#include "codec.h"
22#include "entropy_coding.h"
23#include "pitch_estimator.h"
24#include "settings.h"
25#include "structs.h"
26
27
28
29
30int16_t WebRtcIsacfix_DecodeImpl(int16_t       *signal_out16,
31                                 ISACFIX_DecInst_t *ISACdec_obj,
32                                 int16_t       *current_framesamples)
33{
34  int k;
35  int err;
36  int16_t BWno;
37  int16_t len = 0;
38
39  int16_t model;
40
41
42  int16_t Vector_Word16_1[FRAMESAMPLES/2];
43  int16_t Vector_Word16_2[FRAMESAMPLES/2];
44
45  int32_t Vector_Word32_1[FRAMESAMPLES/2];
46  int32_t Vector_Word32_2[FRAMESAMPLES/2];
47
48  int16_t lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
49  int16_t hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
50  int32_t gain_lo_hiQ17[2*SUBFRAMES];
51
52  int16_t PitchLags_Q7[PITCH_SUBFRAMES];
53  int16_t PitchGains_Q12[PITCH_SUBFRAMES];
54  int16_t AvgPitchGain_Q12;
55
56  int16_t tmp_1, tmp_2;
57  int32_t tmp32a, tmp32b;
58  int16_t gainQ13;
59
60
61  int16_t frame_nb; /* counter */
62  int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */
63  static const int16_t kProcessedSamples = 480; /* 480 (for both 30, 60 ms) */
64
65  /* PLC */
66  int16_t overlapWin[ 240 ];
67
68  (ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
69  (ISACdec_obj->bitstr_obj).streamval = 0;
70  (ISACdec_obj->bitstr_obj).stream_index = 0;
71  (ISACdec_obj->bitstr_obj).full = 1;
72
73
74  /* decode framelength and BW estimation - not used, only for stream pointer*/
75  err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples);
76  if (err<0)  // error check
77    return err;
78
79  frame_mode = *current_framesamples / MAX_FRAMESAMPLES;  /* 0, or 1 */
80
81  err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
82  if (err<0)  // error check
83    return err;
84
85  /* one loop if it's one frame (30ms), two loops if two frames bundled together
86   * (60ms) */
87  for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
88
89    /* decode & dequantize pitch parameters */
90    err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12);
91    if (err<0)  // error check
92      return err;
93
94    err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7);
95    if (err<0)  // error check
96      return err;
97
98    AvgPitchGain_Q12 = (int16_t)(((int32_t)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2);
99
100    /* decode & dequantize FiltCoef */
101    err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
102                                  &ISACdec_obj->bitstr_obj, &model);
103
104    if (err<0)  // error check
105      return err;
106
107    /* decode & dequantize spectrum */
108    len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12);
109    if (len < 0)  // error check
110      return len;
111
112    // Why does this need Q16 in and out? /JS
113    WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);
114
115    for (k=0; k<FRAMESAMPLES/2; k++) {
116      Vector_Word16_1[k] = (int16_t)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9
117    }
118
119    /* ----  If this is recovery frame ---- */
120    if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
121    {
122      (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
123      if( (ISACdec_obj->plcstr_obj).B < 1000 )
124      {
125        (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
126      }
127
128      ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
129      ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
130      ISACdec_obj->plcstr_obj.pitchCycles = 0;
131
132      PitchGains_Q12[0] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[0], 700, 10 );
133
134      /* ---- Add-overlap ---- */
135      WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
136      for( k = 0; k < RECOVERY_OVERLAP; k++ )
137        Vector_Word16_1[k] = WebRtcSpl_AddSatW16(
138            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( (ISACdec_obj->plcstr_obj).overlapLP[k], overlapWin[RECOVERY_OVERLAP - k - 1], 14),
139            (int16_t)WEBRTC_SPL_MUL_16_16_RSFT( Vector_Word16_1[k], overlapWin[k], 14) );
140
141
142
143    }
144
145    /* --- Store side info --- */
146    if( frame_nb == frame_mode )
147    {
148      /* --- LPC info */
149      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
150      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
151      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
152      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];
153
154      /* --- LTP info */
155      (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
156      (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
157      (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];
158
159      if( PitchLags_Q7[3] < 3000 )
160        (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];
161
162      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );
163
164    }
165    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
166
167    /* inverse pitch filter */
168    WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);
169
170    if( frame_nb == frame_mode )
171    {
172      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
173    }
174
175
176    /* reduce gain to compensate for pitch enhancer */
177    /* gain = 1.0f - 0.45f * AvgPitchGain; */
178    tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18
179    tmp32b = 262144 - tmp32a;  // Q18
180    gainQ13 = (int16_t) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13
181
182    for (k = 0; k < FRAMESAMPLES/2; k++)
183    {
184      Vector_Word32_1[k] = (int32_t) WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(Vector_Word16_2[k], gainQ13), 3); // Q25
185    }
186
187
188    /* perceptual post-filtering (using normalized lattice filter) */
189    WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
190                                      Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
191
192    /* --- Store Highpass Residual --- */
193    for (k = 0; k < FRAMESAMPLES/2; k++)
194      Vector_Word32_1[k]    = WEBRTC_SPL_LSHIFT_W32(Vector_Word32_2[k], 9); // Q16 -> Q25
195
196    for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
197      (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];
198
199
200    WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
201                                      Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
202
203    /* recombine the 2 bands */
204
205    /* Form the polyphase signals, and compensate for DC offset */
206    for (k=0;k<FRAMESAMPLES/2;k++) {
207      tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
208      tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
209      Vector_Word16_1[k] = tmp_1;
210      Vector_Word16_2[k] = tmp_2;
211    }
212
213    WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
214                                    Vector_Word16_2,
215                                    signal_out16 + frame_nb * kProcessedSamples,
216                                    &ISACdec_obj->postfiltbankstr_obj);
217
218  }
219  return len;
220}
221