Mercurial > hg > aimc
comparison carfac/sai_test.cc @ 642:20f64146c2ce
Initial translation of SAI code to C++.
This only implements the simple (as opposed to the layered) SAI, as
implemented in SAI_Run.m.
author | ronw@google.com |
---|---|
date | Fri, 31 May 2013 21:46:48 +0000 |
parents | |
children | 8b70f4cf00c7 |
comparison
equal
deleted
inserted
replaced
641:fe8ac95fcf9e | 642:20f64146c2ce |
---|---|
1 // Copyright 2013, Google, Inc. | |
2 // Author: Ron Weiss <ronw@google.com> | |
3 // | |
4 // This C++ file is part of an implementation of Lyon's cochlear model: | |
5 // "Cascade of Asymmetric Resonators with Fast-Acting Compression" | |
6 // to supplement Lyon's upcoming book "Human and Machine Hearing" | |
7 // | |
8 // Licensed under the Apache License, Version 2.0 (the "License"); | |
9 // you may not use this file except in compliance with the License. | |
10 // You may obtain a copy of the License at | |
11 // | |
12 // http://www.apache.org/licenses/LICENSE-2.0 | |
13 // | |
14 // Unless required by applicable law or agreed to in writing, software | |
15 // distributed under the License is distributed on an "AS IS" BASIS, | |
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
17 // See the License for the specific language governing permissions and | |
18 // limitations under the License. | |
19 | |
20 #include "sai.h" | |
21 | |
22 #include <iostream> | |
23 #include <vector> | |
24 | |
25 #include "gtest/gtest.h" | |
26 | |
27 using testing::Values; | |
28 using std::vector; | |
29 | |
30 vector<FloatArray> CreateZeroSegment(int n_ch, int length) { | |
31 vector<FloatArray> segment; | |
32 for (int i = 0; i < length; ++i) { | |
33 segment.push_back(FloatArray::Zero(n_ch)); | |
34 } | |
35 return segment; | |
36 } | |
37 | |
38 bool HasPeakAt(const Float2dArray& frame, int index) { | |
39 if (index == 0) { | |
40 return frame(index) > frame(index + 1); | |
41 } else if (index == frame.size() - 1) { | |
42 return frame(index) > frame(index - 1); | |
43 } | |
44 return frame(index) > frame(index + 1) && frame(index) > frame(index - 1); | |
45 } | |
46 | |
47 class SAIPeriodicInputTest | |
48 : public testing::TestWithParam<std::tr1::tuple<int, int>> { | |
49 protected: | |
50 void SetUp() { | |
51 period_ = std::tr1::get<0>(GetParam()); | |
52 phase_ = std::tr1::get<1>(GetParam()); | |
53 } | |
54 | |
55 int period_; | |
56 int phase_; | |
57 }; | |
58 | |
59 TEST_P(SAIPeriodicInputTest, SingleChannelPulseTrain) { | |
60 vector<FloatArray> segment = CreateZeroSegment(1, 38); | |
61 for (int i = phase_; i < segment.size(); i += period_) { | |
62 segment[i](0) = 1; | |
63 } | |
64 | |
65 SAIParams sai_params; | |
66 sai_params.window_width = segment.size(); | |
67 sai_params.n_ch = 1; | |
68 sai_params.width = 15; | |
69 // Half of the SAI should come from the future. | |
70 // sai_params.future_lags = sai_params.width / 2; | |
71 sai_params.future_lags = 0; | |
72 sai_params.n_window_pos = 2; | |
73 | |
74 SAI sai(sai_params); | |
75 Float2dArray sai_frame; | |
76 sai.RunSegment(segment, &sai_frame); | |
77 | |
78 // The output should have peaks at the same positions, regardless of | |
79 // input phase. | |
80 for (int i = sai_frame.size() - 1; i >= 0 ; i -= period_) { | |
81 EXPECT_TRUE(HasPeakAt(sai_frame, i)); | |
82 } | |
83 | |
84 for (int i = 0; i < segment.size(); ++i) { | |
85 std::cout << segment[i](0) << " "; | |
86 } | |
87 std::cout << "\n"; | |
88 for (int i = 0; i < sai_frame.size(); ++i) { | |
89 std::cout << sai_frame(i) << " "; | |
90 } | |
91 std::cout << "\n"; | |
92 } | |
93 INSTANTIATE_TEST_CASE_P(PeriodicInputVariations, SAIPeriodicInputTest, | |
94 testing::Combine(Values(25, 10, 5, 2), // periods. | |
95 Values(0, 3))); // phases. |