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
WebRtcIsacfix_DecodeImpl(int16_t * signal_out16,IsacFixDecoderInstance * ISACdec_obj,size_t * current_framesamples)30 int WebRtcIsacfix_DecodeImpl(int16_t* signal_out16,
31 IsacFixDecoderInstance* ISACdec_obj,
32 size_t* current_framesamples)
33 {
34 int k;
35 int err;
36 int16_t BWno;
37 int 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;
58 int16_t gainQ13;
59
60
61 size_t frame_nb; /* counter */
62 size_t frame_mode; /* 0 for 30ms, 1 for 60ms */
63 static const size_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 // Q16 -> Q9.
117 Vector_Word16_1[k] = (int16_t)((Vector_Word32_1[k] + 64) >> 7);
118 }
119
120 /* ---- If this is recovery frame ---- */
121 if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
122 {
123 (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
124 if( (ISACdec_obj->plcstr_obj).B < 1000 )
125 {
126 (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
127 }
128
129 ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX; /* DECAY_RATE is in Q15 */
130 ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX; /* DECAY_RATE is in Q15 */
131 ISACdec_obj->plcstr_obj.pitchCycles = 0;
132
133 PitchGains_Q12[0] = (int16_t)(PitchGains_Q12[0] * 700 >> 10);
134
135 /* ---- Add-overlap ---- */
136 WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
137 for( k = 0; k < RECOVERY_OVERLAP; k++ )
138 Vector_Word16_1[k] = WebRtcSpl_AddSatW16(
139 (int16_t)(ISACdec_obj->plcstr_obj.overlapLP[k] *
140 overlapWin[RECOVERY_OVERLAP - k - 1] >> 14),
141 (int16_t)(Vector_Word16_1[k] * overlapWin[k] >> 14));
142
143
144
145 }
146
147 /* --- Store side info --- */
148 if( frame_nb == frame_mode )
149 {
150 /* --- LPC info */
151 WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
152 WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
153 (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
154 (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];
155
156 /* --- LTP info */
157 (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
158 (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
159 (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];
160
161 if( PitchLags_Q7[3] < 3000 )
162 (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];
163
164 WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );
165
166 }
167 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
168
169 /* inverse pitch filter */
170 WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);
171
172 if( frame_nb == frame_mode )
173 {
174 WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
175 }
176
177
178 /* reduce gain to compensate for pitch enhancer */
179 /* gain = 1.0f - 0.45f * AvgPitchGain; */
180 tmp32a = AvgPitchGain_Q12 * 29; // Q18
181 gainQ13 = (int16_t)((262144 - tmp32a) >> 5); // Q18 -> Q13.
182
183 for (k = 0; k < FRAMESAMPLES/2; k++)
184 {
185 Vector_Word32_1[k] = (Vector_Word16_2[k] * gainQ13) << 3; // Q25
186 }
187
188
189 /* perceptual post-filtering (using normalized lattice filter) */
190 WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
191 Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
192
193 /* --- Store Highpass Residual --- */
194 for (k = 0; k < FRAMESAMPLES/2; k++)
195 Vector_Word32_1[k] = Vector_Word32_2[k] << 9; // Q16 -> Q25
196
197 for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
198 (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];
199
200
201 WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
202 Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
203
204 /* recombine the 2 bands */
205
206 /* Form the polyphase signals, and compensate for DC offset */
207 for (k=0;k<FRAMESAMPLES/2;k++) {
208 tmp_1 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
209 tmp_2 = (int16_t)WebRtcSpl_SatW32ToW16(((int32_t)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
210 Vector_Word16_1[k] = tmp_1;
211 Vector_Word16_2[k] = tmp_2;
212 }
213
214 WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
215 Vector_Word16_2,
216 signal_out16 + frame_nb * kProcessedSamples,
217 &ISACdec_obj->postfiltbankstr_obj);
218
219 }
220 return len;
221 }
222