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
13 iLBC Speech Coder ANSI-C Source Code
14
15 WebRtcIlbcfix_SimpleInterpolateLsf.c
16
17******************************************************************/
18
19#include "defines.h"
20#include "lsf_interpolate_to_poly_enc.h"
21#include "bw_expand.h"
22#include "constants.h"
23
24/*----------------------------------------------------------------*
25 *  lsf interpolator (subrutine to LPCencode)
26 *---------------------------------------------------------------*/
27
28void WebRtcIlbcfix_SimpleInterpolateLsf(
29    int16_t *syntdenum, /* (o) the synthesis filter denominator
30                                   resulting from the quantized
31                                   interpolated lsf Q12 */
32    int16_t *weightdenum, /* (o) the weighting filter denominator
33                                   resulting from the unquantized
34                                   interpolated lsf Q12 */
35    int16_t *lsf,  /* (i) the unquantized lsf coefficients Q13 */
36    int16_t *lsfdeq,  /* (i) the dequantized lsf coefficients Q13 */
37    int16_t *lsfold,  /* (i) the unquantized lsf coefficients of
38                                           the previous signal frame Q13 */
39    int16_t *lsfdeqold, /* (i) the dequantized lsf coefficients of the
40                                   previous signal frame Q13 */
41    int16_t length,  /* (i) should equate FILTERORDER */
42    IlbcEncoder *iLBCenc_inst
43    /* (i/o) the encoder state structure */
44                                        ) {
45  size_t i;
46  int pos, lp_length;
47
48  int16_t *lsf2, *lsfdeq2;
49  /* Stack based */
50  int16_t lp[LPC_FILTERORDER + 1];
51
52  lsf2 = lsf + length;
53  lsfdeq2 = lsfdeq + length;
54  lp_length = length + 1;
55
56  if (iLBCenc_inst->mode==30) {
57    /* subframe 1: Interpolation between old and first set of
58       lsf coefficients */
59
60    /* Calculate Analysis/Syntehsis filter from quantized LSF */
61    WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeqold, lsfdeq,
62                                         WebRtcIlbcfix_kLsfWeight30ms[0],
63                                         length);
64    WEBRTC_SPL_MEMCPY_W16(syntdenum, lp, lp_length);
65
66    /* Calculate Weighting filter from quantized LSF */
67    WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfold, lsf,
68                                         WebRtcIlbcfix_kLsfWeight30ms[0],
69                                         length);
70    WebRtcIlbcfix_BwExpand(weightdenum, lp,
71                           (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
72                           (int16_t)lp_length);
73
74    /* subframe 2 to 6: Interpolation between first and second
75       set of lsf coefficients */
76
77    pos = lp_length;
78    for (i = 1; i < iLBCenc_inst->nsub; i++) {
79
80      /* Calculate Analysis/Syntehsis filter from quantized LSF */
81      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeq, lsfdeq2,
82                                           WebRtcIlbcfix_kLsfWeight30ms[i],
83                                           length);
84      WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length);
85
86      /* Calculate Weighting filter from quantized LSF */
87      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsf, lsf2,
88                                           WebRtcIlbcfix_kLsfWeight30ms[i],
89                                           length);
90      WebRtcIlbcfix_BwExpand(weightdenum + pos, lp,
91                             (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
92                             (int16_t)lp_length);
93
94      pos += lp_length;
95    }
96
97    /* update memory */
98
99    WEBRTC_SPL_MEMCPY_W16(lsfold, lsf2, length);
100    WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq2, length);
101
102  } else { /* iLBCenc_inst->mode==20 */
103    pos = 0;
104    for (i = 0; i < iLBCenc_inst->nsub; i++) {
105
106      /* Calculate Analysis/Syntehsis filter from quantized LSF */
107      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfdeqold, lsfdeq,
108                                           WebRtcIlbcfix_kLsfWeight20ms[i],
109                                           length);
110      WEBRTC_SPL_MEMCPY_W16(syntdenum + pos, lp, lp_length);
111
112      /* Calculate Weighting filter from quantized LSF */
113      WebRtcIlbcfix_LsfInterpolate2PloyEnc(lp, lsfold, lsf,
114                                           WebRtcIlbcfix_kLsfWeight20ms[i],
115                                           length);
116      WebRtcIlbcfix_BwExpand(weightdenum+pos, lp,
117                             (int16_t*)WebRtcIlbcfix_kLpcChirpWeightDenum,
118                             (int16_t)lp_length);
119
120      pos += lp_length;
121    }
122
123    /* update memory */
124
125    WEBRTC_SPL_MEMCPY_W16(lsfold, lsf, length);
126    WEBRTC_SPL_MEMCPY_W16(lsfdeqold, lsfdeq, length);
127
128  }
129
130  return;
131}
132