annotate carfac/carfac_test.cc @ 646:e76951e4da20

Style fixes. - Fix most lint errors found by http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py - Clean up commenting style. - Alphabetize #includes and using statements.
author ronw@google.com
date Tue, 11 Jun 2013 20:41:15 +0000
parents 8b70f4cf00c7
children 749b5aed61f6
rev   line source
alexbrandmeyer@626 1 //
alexbrandmeyer@626 2 // carfac_test.cc
alexbrandmeyer@626 3 // CARFAC Open Source C++ Library
alexbrandmeyer@626 4 //
alexbrandmeyer@626 5 // Created by Alex Brandmeyer on 5/22/13.
alexbrandmeyer@626 6 //
alexbrandmeyer@626 7 // This C++ file is part of an implementation of Lyon's cochlear model:
alexbrandmeyer@626 8 // "Cascade of Asymmetric Resonators with Fast-Acting Compression"
alexbrandmeyer@626 9 // to supplement Lyon's upcoming book "Human and Machine Hearing"
alexbrandmeyer@626 10 //
alexbrandmeyer@626 11 // Licensed under the Apache License, Version 2.0 (the "License");
alexbrandmeyer@626 12 // you may not use this file except in compliance with the License.
alexbrandmeyer@626 13 // You may obtain a copy of the License at
alexbrandmeyer@626 14 //
alexbrandmeyer@626 15 // http://www.apache.org/licenses/LICENSE-2.0
alexbrandmeyer@626 16 //
alexbrandmeyer@626 17 // Unless required by applicable law or agreed to in writing, software
alexbrandmeyer@626 18 // distributed under the License is distributed on an "AS IS" BASIS,
alexbrandmeyer@626 19 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
alexbrandmeyer@626 20 // See the License for the specific language governing permissions and
alexbrandmeyer@626 21 // limitations under the License.
alexbrandmeyer@626 22
ronw@646 23 #include <fstream>
alexbrandmeyer@636 24 #include <string>
alexbrandmeyer@640 25 #include <vector>
ronw@642 26
ronw@642 27 #include "gtest/gtest.h"
alexbrandmeyer@643 28
ronw@646 29 #include "agc.h"
alexbrandmeyer@643 30 #include "car.h"
alexbrandmeyer@636 31 #include "carfac.h"
alexbrandmeyer@643 32 #include "common.h"
ronw@646 33 #include "ihc.h"
alexbrandmeyer@637 34
alexbrandmeyer@636 35 using std::ifstream;
alexbrandmeyer@636 36 using std::ofstream;
ronw@646 37 using std::string;
ronw@646 38 using std::vector;
alexbrandmeyer@636 39
alexbrandmeyer@637 40 // This is the 'test_data' subdirectory of aimc/carfac that specifies where to
alexbrandmeyer@637 41 // locate the text files produced by 'CARFAC_GenerateTestData.m' for comparing
alexbrandmeyer@637 42 // the ouput of the Matlab version of CARFAC with this C++ version.
alexbrandmeyer@637 43 static const char* kTestSourceDir= "./test_data/";
alexbrandmeyer@643 44 // Here we specify the level to which the output should match (2 decimals).
alexbrandmeyer@643 45 static const float kPrecisionLevel = 1.0e-2;
ronw@630 46
alexbrandmeyer@626 47 // Three helper functions are defined here for loading the test data generated
alexbrandmeyer@626 48 // by the Matlab version of CARFAC.
alexbrandmeyer@643 49 // This loads one-dimensional ArrayXs from single-column text files.
ronw@646 50 void WriteNAPOutput(const CARFACOutput& output, const string filename,
ronw@646 51 int ear) {
alexbrandmeyer@637 52 string fullfile = kTestSourceDir + filename;
alexbrandmeyer@636 53 ofstream ofile(fullfile.c_str());
alexbrandmeyer@643 54 int32_t num_timepoints = output.nap().size();
alexbrandmeyer@637 55 int channels = output.nap()[0][0].size();
alexbrandmeyer@636 56 if (ofile.is_open()) {
alexbrandmeyer@643 57 for (int32_t i = 0; i < num_timepoints; ++i) {
alexbrandmeyer@636 58 for (int j = 0; j < channels; ++j) {
alexbrandmeyer@637 59 ofile << output.nap()[i][ear](j);
ronw@646 60 if (j < channels - 1) {
alexbrandmeyer@636 61 ofile << " ";
alexbrandmeyer@636 62 }
alexbrandmeyer@636 63 }
alexbrandmeyer@636 64 ofile << "\n";
alexbrandmeyer@636 65 }
alexbrandmeyer@636 66 }
alexbrandmeyer@636 67 ofile.close();
alexbrandmeyer@636 68 }
alexbrandmeyer@636 69
alexbrandmeyer@643 70 ArrayX LoadTestData(const string filename, const int number_points) {
alexbrandmeyer@637 71 string fullfile = kTestSourceDir + filename;
alexbrandmeyer@636 72 ifstream file(fullfile.c_str());
alexbrandmeyer@626 73 FPType myarray[number_points];
alexbrandmeyer@643 74 ArrayX output(number_points);
alexbrandmeyer@626 75 if (file.is_open()) {
alexbrandmeyer@626 76 for (int i = 0; i < number_points; ++i) {
alexbrandmeyer@626 77 file >> myarray[i];
alexbrandmeyer@626 78 output(i) = myarray[i];
alexbrandmeyer@626 79 }
alexbrandmeyer@626 80 }
alexbrandmeyer@636 81 file.close();
alexbrandmeyer@626 82 return output;
alexbrandmeyer@626 83 }
alexbrandmeyer@626 84
alexbrandmeyer@643 85 // This loads a vector of ArrayXs from multi-column text files.
alexbrandmeyer@643 86 vector<ArrayX> Load2dTestData(const string filename, const int rows,
alexbrandmeyer@626 87 const int columns) {
alexbrandmeyer@637 88 string fullfile = kTestSourceDir + filename;
alexbrandmeyer@636 89 ifstream file(fullfile.c_str());
alexbrandmeyer@626 90 FPType myarray[rows][columns];
alexbrandmeyer@643 91 vector<ArrayX> output;
alexbrandmeyer@626 92 output.resize(rows);
alexbrandmeyer@626 93 for (auto& timepoint : output) {
alexbrandmeyer@626 94 timepoint.resize(columns);
alexbrandmeyer@626 95 }
alexbrandmeyer@626 96 if (file.is_open()) {
alexbrandmeyer@626 97 for (int i = 0; i < rows; ++i) {
alexbrandmeyer@626 98 for (int j = 0; j < columns; ++j) {
alexbrandmeyer@626 99 file >> myarray[i][j];
alexbrandmeyer@626 100 output[i](j) = myarray[i][j];
alexbrandmeyer@626 101 }
alexbrandmeyer@626 102 }
alexbrandmeyer@626 103 }
alexbrandmeyer@636 104 file.close();
alexbrandmeyer@626 105 return output;
alexbrandmeyer@626 106 }
alexbrandmeyer@626 107
alexbrandmeyer@626 108 // This loads two dimensional vectors of audio data using data generated in
alexbrandmeyer@626 109 // Matlab using the wavread() function.
alexbrandmeyer@636 110 vector<vector<float>> Load2dAudioVector(string filename, int timepoints,
alexbrandmeyer@636 111 int channels) {
alexbrandmeyer@637 112 string fullfile = kTestSourceDir + filename;
alexbrandmeyer@636 113 ifstream file(fullfile.c_str());
alexbrandmeyer@636 114 vector<vector<float>> output;
alexbrandmeyer@626 115 output.resize(channels);
alexbrandmeyer@626 116 for (auto& channel : output) {
alexbrandmeyer@626 117 channel.resize(timepoints);
alexbrandmeyer@626 118 }
alexbrandmeyer@626 119 if (file.is_open()) {
alexbrandmeyer@626 120 for (int i = 0; i < timepoints; ++i) {
alexbrandmeyer@626 121 for (int j = 0; j < channels; ++j) {
alexbrandmeyer@626 122 file >> output[j][i];
alexbrandmeyer@626 123 }
alexbrandmeyer@626 124 }
alexbrandmeyer@626 125 }
alexbrandmeyer@636 126 file.close();
alexbrandmeyer@626 127 return output;
alexbrandmeyer@626 128 }
alexbrandmeyer@626 129
alexbrandmeyer@636 130 TEST(CARFACTest, Binaural_Output_test) {
alexbrandmeyer@643 131 int num_timepoints = 882;
alexbrandmeyer@643 132 int num_channels = 71;
alexbrandmeyer@643 133 int num_ears = 2;
alexbrandmeyer@637 134 string filename = "binaural_test_nap1.txt";
alexbrandmeyer@643 135 vector<ArrayX> nap1 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 136 filename = "binaural_test_bm1.txt";
alexbrandmeyer@643 137 vector<ArrayX> bm1 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 138 filename = "binaural_test_nap2.txt";
alexbrandmeyer@643 139 vector<ArrayX> nap2 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 140 filename = "binaural_test_bm2.txt";
alexbrandmeyer@643 141 vector<ArrayX> bm2 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 142 filename = "file_signal_binaural_test.txt";
alexbrandmeyer@643 143 vector<vector<float>> sound_data = Load2dAudioVector(filename, num_timepoints,
alexbrandmeyer@643 144 num_ears);
alexbrandmeyer@626 145 CARParams car_params;
alexbrandmeyer@636 146 IHCParams ihc_params;
alexbrandmeyer@636 147 AGCParams agc_params;
alexbrandmeyer@643 148 CARFAC mycf(num_ears, 22050, car_params, ihc_params, agc_params);
ronw@646 149 CARFACOutput my_output(true, true, false, false);
ronw@641 150 const bool kOpenLoop = false;
ronw@641 151 const int length = sound_data[0].size();
ronw@641 152 mycf.RunSegment(sound_data, 0, length, kOpenLoop, &my_output);
alexbrandmeyer@636 153 filename = "cpp_nap_output_1_binaural_test.txt";
alexbrandmeyer@636 154 WriteNAPOutput(my_output, filename, 0);
alexbrandmeyer@636 155 filename = "cpp_nap_output_2_binaural_test.txt";
alexbrandmeyer@636 156 WriteNAPOutput(my_output, filename, 1);
alexbrandmeyer@636 157 int ear = 0;
alexbrandmeyer@636 158 int n_ch = 71;
alexbrandmeyer@643 159 for (int timepoint = 0; timepoint < num_timepoints; ++timepoint) {
alexbrandmeyer@636 160 for (int channel = 0; channel < n_ch; ++channel) {
alexbrandmeyer@637 161 FPType cplusplus = my_output.nap()[timepoint][ear](channel);
alexbrandmeyer@636 162 FPType matlab = nap1[timepoint](channel);
alexbrandmeyer@637 163 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@637 164 cplusplus = my_output.bm()[timepoint][ear](channel);
alexbrandmeyer@636 165 matlab = bm1[timepoint](channel);
alexbrandmeyer@637 166 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@636 167 }
alexbrandmeyer@626 168 }
alexbrandmeyer@636 169 ear = 1;
alexbrandmeyer@643 170 for (int timepoint = 0; timepoint < num_timepoints; ++timepoint) {
alexbrandmeyer@636 171 for (int channel = 0; channel < n_ch; ++channel) {
alexbrandmeyer@637 172 FPType cplusplus = my_output.nap()[timepoint][ear](channel);
alexbrandmeyer@636 173 FPType matlab = nap2[timepoint](channel);
alexbrandmeyer@637 174 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@637 175 cplusplus = my_output.bm()[timepoint][ear](channel);
alexbrandmeyer@636 176 matlab = bm2[timepoint](channel);
alexbrandmeyer@637 177 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@626 178 }
alexbrandmeyer@626 179 }
alexbrandmeyer@626 180 }
alexbrandmeyer@626 181
alexbrandmeyer@636 182 TEST(CARFACTest, Long_Output_test) {
alexbrandmeyer@643 183 int num_timepoints = 2000;
alexbrandmeyer@643 184 int num_channels = 83;
alexbrandmeyer@643 185 int num_ears = 2;
alexbrandmeyer@636 186 string filename = "long_test_nap1.txt";
alexbrandmeyer@643 187 vector<ArrayX> nap1 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 188 filename = "long_test_bm1.txt";
alexbrandmeyer@643 189 vector<ArrayX> bm1 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 190 filename = "long_test_nap2.txt";
alexbrandmeyer@643 191 vector<ArrayX> nap2 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 192 filename = "long_test_bm2.txt";
alexbrandmeyer@643 193 vector<ArrayX> bm2 = Load2dTestData(filename, num_timepoints, num_channels);
alexbrandmeyer@636 194 filename = "file_signal_long_test.txt";
alexbrandmeyer@643 195 vector<vector<float>> sound_data = Load2dAudioVector(filename, num_timepoints,
alexbrandmeyer@643 196 num_ears);
alexbrandmeyer@626 197 CARParams car_params;
alexbrandmeyer@626 198 IHCParams ihc_params;
alexbrandmeyer@626 199 AGCParams agc_params;
alexbrandmeyer@643 200 CARFAC mycf(num_ears, 44100, car_params, ihc_params, agc_params);
ronw@646 201 CARFACOutput my_output(true, true, false, false);
ronw@641 202 const bool kOpenLoop = false;
ronw@641 203 const int length = sound_data[0].size();
ronw@641 204 mycf.RunSegment(sound_data, 0, length, kOpenLoop, &my_output);
alexbrandmeyer@636 205 filename = "cpp_nap_output_1_long_test.txt";
alexbrandmeyer@636 206 WriteNAPOutput(my_output, filename, 0);
alexbrandmeyer@636 207 filename = "cpp_nap_output_2_long_test.txt";
alexbrandmeyer@636 208 WriteNAPOutput(my_output, filename, 1);
alexbrandmeyer@636 209 int ear = 0;
alexbrandmeyer@643 210 for (int timepoint = 0; timepoint < num_timepoints; ++timepoint) {
alexbrandmeyer@643 211 for (int channel = 0; channel < num_channels; ++channel) {
alexbrandmeyer@637 212 FPType cplusplus = my_output.nap()[timepoint][ear](channel);
alexbrandmeyer@636 213 FPType matlab = nap1[timepoint](channel);
alexbrandmeyer@637 214 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@637 215 cplusplus = my_output.bm()[timepoint][ear](channel);
alexbrandmeyer@636 216 matlab = bm1[timepoint](channel);
alexbrandmeyer@637 217 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@636 218 }
alexbrandmeyer@626 219 }
alexbrandmeyer@636 220 ear = 1;
alexbrandmeyer@643 221 for (int timepoint = 0; timepoint < num_timepoints; ++timepoint) {
alexbrandmeyer@643 222 for (int channel = 0; channel < num_channels; ++channel) {
alexbrandmeyer@637 223 FPType cplusplus = my_output.nap()[timepoint][ear](channel);
alexbrandmeyer@636 224 FPType matlab = nap2[timepoint](channel);
alexbrandmeyer@637 225 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@637 226 cplusplus = my_output.bm()[timepoint][ear](channel);
alexbrandmeyer@636 227 matlab = bm2[timepoint](channel);
alexbrandmeyer@637 228 ASSERT_NEAR(cplusplus, matlab, kPrecisionLevel);
alexbrandmeyer@626 229 }
alexbrandmeyer@626 230 }
ronw@646 231 }