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#include <typedefs.h>
11
12#include "gtest/gtest.h"
13#include "modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
14#include "modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h"
15#include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
16#include "system_wrappers/interface/cpu_features_wrapper.h"
17
18class IsacUnitTest : public testing::Test {
19 protected:
20  // Pass a function pointer to the Tester function.
21  void CalculateResidualEnergyTester(CalculateResidualEnergy
22                                     CalculateResidualEnergyFunction) {
23    const int kIntOrder = 10;
24    const int32_t kInt32QDomain = 5;
25    const int kIntShift = 11;
26    int16_t a[kIntOrder + 1] = {32760, 122, 7, 0, -32760, -3958,
27        -48, 18745, 498, 9, 23456};
28    int32_t corr[kIntOrder + 1] = {11443647, -27495, 0,
29        98745, -11443600, 1, 1, 498, 9, 888, 23456};
30    int q_shift_residual = 0;
31    int32_t residual_energy = 0;
32
33    // Test the code path where (residual_energy >= 0x10000).
34    residual_energy = CalculateResidualEnergyFunction(kIntOrder,
35        kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
36    EXPECT_EQ(1789023310, residual_energy);
37    EXPECT_EQ(2, q_shift_residual);
38
39    // Test the code path where (residual_energy < 0x10000)
40    // and ((energy & 0x8000) != 0).
41    for(int i = 0; i < kIntOrder + 1; i++) {
42      a[i] = 24575 >> i;
43      corr[i] = i;
44    }
45    residual_energy = CalculateResidualEnergyFunction(kIntOrder,
46        kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
47    EXPECT_EQ(1595279092, residual_energy);
48    EXPECT_EQ(26, q_shift_residual);
49
50    // Test the code path where (residual_energy <= 0x7fff).
51    for(int i = 0; i < kIntOrder + 1; i++) {
52      a[i] = 2457 >> i;
53    }
54    residual_energy = CalculateResidualEnergyFunction(kIntOrder,
55        kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
56    EXPECT_EQ(2029266944, residual_energy);
57    EXPECT_EQ(33, q_shift_residual);
58  }
59};
60
61TEST_F(IsacUnitTest, CalculateResidualEnergyTest) {
62  CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyC);
63#ifdef WEBRTC_DETECT_ARM_NEON
64  if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
65    CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyNeon);
66  }
67#elif defined(WEBRTC_ARCH_ARM_NEON)
68  CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyNeon);
69#endif
70}
71
72TEST_F(IsacUnitTest, HighpassFilterFixDec32Test) {
73  const int kSamples = 20;
74  int16_t in[kSamples];
75  int32_t state[2] = {12345, 987654};
76#ifdef WEBRTC_ARCH_ARM_V7
77  int32_t out[kSamples] = {-1040, -1035, -22875, -1397, -27604, 20018, 7917,
78    -1279, -8552, -14494, -7558, -23537, -27258, -30554, -32768, -3432, -32768,
79    25215, -27536, 22436};
80#else
81  int32_t out[kSamples] = {-1040, -1035, -22875, -1397, -27604, 20017, 7915,
82    -1280, -8554, -14496, -7561, -23541, -27263, -30560, -32768, -3441, -32768,
83    25203, -27550, 22419};
84#endif
85
86  for(int i = 0; i < kSamples; i++) {
87    in[i] = WEBRTC_SPL_WORD32_MAX / (i + 1);
88  }
89
90  WebRtcIsacfix_HighpassFilterFixDec32(in, kSamples,
91      WebRtcIsacfix_kHPStCoeffOut1Q30, state);
92
93  for(int i = 0; i < kSamples; i++) {
94    EXPECT_EQ(out[i], in[i]);
95  }
96}
97