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#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
12#include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
13
14/* Filter coefficicients in Q15. */
15static const int16_t kDampFilter[PITCH_DAMPORDER] = {
16  -2294, 8192, 20972, 8192, -2294
17};
18
19void WebRtcIsacfix_PitchFilterCore(int loopNumber,
20                                   int16_t gain,
21                                   size_t index,
22                                   int16_t sign,
23                                   int16_t* inputState,
24                                   int16_t* outputBuf2,
25                                   const int16_t* coefficient,
26                                   int16_t* inputBuf,
27                                   int16_t* outputBuf,
28                                   int* index2) {
29  int i = 0, j = 0;  /* Loop counters. */
30  int16_t* ubufQQpos2 = &outputBuf2[PITCH_BUFFSIZE - (index + 2)];
31  int16_t tmpW16 = 0;
32
33  for (i = 0; i < loopNumber; i++) {
34    int32_t tmpW32 = 0;
35
36    /* Filter to get fractional pitch. */
37    for (j = 0; j < PITCH_FRACORDER; j++) {
38      tmpW32 += ubufQQpos2[*index2 + j] * coefficient[j];
39    }
40
41    /* Saturate to avoid overflow in tmpW16. */
42    tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
43    tmpW32 += 8192;
44    tmpW16 = (int16_t)(tmpW32 >> 14);
45
46    /* Shift low pass filter state. */
47    memmove(&inputState[1], &inputState[0],
48            (PITCH_DAMPORDER - 1) * sizeof(int16_t));
49    inputState[0] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
50                      gain, tmpW16, 12);
51
52    /* Low pass filter. */
53    tmpW32 = 0;
54    /* TODO(kma): Define a static inline function WebRtcSpl_DotProduct()
55       in spl_inl.h to replace this and other similar loops. */
56    for (j = 0; j < PITCH_DAMPORDER; j++) {
57      tmpW32 += inputState[j] * kDampFilter[j];
58    }
59
60    /* Saturate to avoid overflow in tmpW16. */
61    tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
62    tmpW32 += 16384;
63    tmpW16 = (int16_t)(tmpW32 >> 15);
64
65    /* Subtract from input and update buffer. */
66    tmpW32 = inputBuf[*index2] - sign * tmpW16;
67    outputBuf[*index2] = WebRtcSpl_SatW32ToW16(tmpW32);
68    tmpW32 = inputBuf[*index2] + outputBuf[*index2];
69    outputBuf2[*index2 + PITCH_BUFFSIZE] = WebRtcSpl_SatW32ToW16(tmpW32);
70
71    (*index2)++;
72  }
73}
74