annotate carfac/carfac_test.cc @ 662:7e18c84ca2b7

Small cleanup of eigen usage in SAI implementation.
author ronw@google.com
date Tue, 16 Jul 2013 19:56:11 +0000
parents 7a0031c321da
children
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@647 23 #include "carfac.h"
ronw@647 24
alexbrandmeyer@636 25 #include <string>
alexbrandmeyer@640 26 #include <vector>
ronw@642 27
ronw@660 28 #include <Eigen/Core>
ronw@660 29
ronw@642 30 #include "gtest/gtest.h"
alexbrandmeyer@643 31
ronw@646 32 #include "agc.h"
alexbrandmeyer@643 33 #include "car.h"
ronw@647 34 #include "carfac_output.h"
alexbrandmeyer@643 35 #include "common.h"
ronw@646 36 #include "ihc.h"
ronw@660 37 #include "test_util.h"
alexbrandmeyer@637 38
ronw@652 39 using std::deque;
ronw@646 40 using std::string;
ronw@646 41 using std::vector;
alexbrandmeyer@636 42
ronw@660 43 // Reads a two dimensional vector of audio data from a text file
ronw@660 44 // containing the output of the Matlab wavread() function.
ronw@660 45 vector<vector<float>> LoadAudio(const string& filename, int timepoints,
ronw@660 46 int num_channels) {
ronw@660 47 return LoadMatrix<vector<float>, false>(filename, timepoints, num_channels);
ronw@660 48 }
ronw@630 49
ronw@652 50 // Writes the CARFAC NAP output to a text file.
ronw@652 51 void WriteNAPOutput(const CARFACOutput& output, const string& filename,
ronw@646 52 int ear) {
ronw@661 53 const int num_samples = output.nap().size();
ronw@661 54 const int num_channels = output.nap()[0][0].size();
ronw@661 55 ArrayXX nap_matrix(num_samples, num_channels);
ronw@661 56 for (int i = 0; i < num_samples; ++i) {
ronw@661 57 nap_matrix.row(i) = output.nap()[i][ear];
alexbrandmeyer@636 58 }
ronw@661 59
ronw@661 60 WriteMatrix(filename, nap_matrix);
alexbrandmeyer@636 61 }
alexbrandmeyer@636 62
ronw@652 63 class CARFACTest : public testing::Test {
ronw@652 64 protected:
ronw@654 65 deque<vector<ArrayX>> LoadTestData(const string& basename,
ronw@654 66 int num_samples,
ronw@654 67 int num_ears,
ronw@654 68 int num_channels) const {
ronw@654 69 deque<vector<ArrayX>> test_data(num_samples, vector<ArrayX>(num_ears));
ronw@654 70 for (int ear = 0; ear < num_ears; ++ear) {
ronw@652 71 string filename = basename + std::to_string(ear + 1) + ".txt";
ronw@660 72 vector<ArrayX> data = LoadMatrix(filename, num_samples, num_channels);
ronw@654 73 for (int i = 0; i < num_samples; ++i) {
ronw@652 74 test_data[i][ear] = data[i];
ronw@652 75 }
ronw@652 76 }
ronw@652 77 return test_data;
alexbrandmeyer@626 78 }
ronw@652 79
ronw@652 80 void AssertCARFACOutputNear(const deque<vector<ArrayX>>& expected,
ronw@652 81 const deque<vector<ArrayX>>& actual,
ronw@654 82 int num_samples,
ronw@660 83 int num_ears) const {
ronw@654 84 for (int timepoint = 0; timepoint < num_samples; ++timepoint) {
ronw@654 85 for (int ear = 0; ear < num_ears; ++ear) {
ronw@660 86 const float kPrecisionLevel = 1.0e-7;
ronw@661 87 AssertArrayNear(expected[timepoint][ear], actual[timepoint][ear],
ronw@661 88 kPrecisionLevel);
ronw@652 89 }
alexbrandmeyer@626 90 }
alexbrandmeyer@626 91 }
ronw@652 92
ronw@660 93 void RunCARFACAndCompareWithMatlab(const string& test_name,
ronw@660 94 int num_samples,
ronw@660 95 int num_ears,
ronw@660 96 int num_channels,
ronw@660 97 FPType sample_rate) const {
ronw@660 98 vector<vector<float>> sound_data =
ronw@660 99 LoadAudio(test_name + "-audio.txt", num_samples, num_ears);
ronw@660 100
ronw@660 101 CARParams car_params;
ronw@660 102 IHCParams ihc_params;
ronw@660 103 AGCParams agc_params;
ronw@660 104 CARFAC carfac(num_ears, sample_rate, car_params, ihc_params, agc_params);
ronw@660 105 CARFACOutput output(true, true, false, false);
ronw@660 106 const bool kOpenLoop = false;
ronw@660 107 const int length = sound_data[0].size();
ronw@660 108 carfac.RunSegment(sound_data, 0, length, kOpenLoop, &output);
ronw@660 109
ronw@660 110 // TODO(ronw): Don't unconditionally overwrite files that are
ronw@660 111 // checked in to the repository on every test run.
ronw@660 112 WriteNAPOutput(output, test_name + "-cpp-nap1.txt", 0);
ronw@660 113 WriteNAPOutput(output, test_name + "-cpp-nap2.txt", 1);
ronw@660 114
ronw@660 115 deque<vector<ArrayX>> expected_nap = LoadTestData(
ronw@660 116 test_name + "-matlab-nap", num_samples, num_ears, num_channels);
ronw@660 117 AssertCARFACOutputNear(expected_nap, output.nap(), num_samples, num_ears);
ronw@660 118 deque<vector<ArrayX>> expected_bm = LoadTestData(
ronw@660 119 test_name + "-matlab-bm", num_samples, num_ears, num_channels);
ronw@660 120 AssertCARFACOutputNear(expected_bm, output.bm(), num_samples, num_ears);
ronw@660 121 }
ronw@652 122 };
ronw@652 123
ronw@660 124 TEST_F(CARFACTest, MatchesMatlabOnBinauralData) {
ronw@654 125 const int kNumSamples = 882;
ronw@654 126 const int kNumEars = 2;
ronw@654 127 const int kNumChannels = 71;
ronw@660 128 const FPType kSampleRate = 22050.0;
ronw@660 129 RunCARFACAndCompareWithMatlab(
ronw@660 130 "binaural_test", kNumSamples, kNumEars, kNumChannels, kSampleRate);
alexbrandmeyer@626 131 }
alexbrandmeyer@626 132
ronw@660 133 TEST_F(CARFACTest, MatchesMatlabOnLongBinauralData) {
ronw@654 134 const int kNumSamples = 2000;
ronw@654 135 const int kNumEars = 2;
ronw@654 136 const int kNumChannels = 83;
ronw@660 137 const FPType kSampleRate = 44100.0;
ronw@660 138 RunCARFACAndCompareWithMatlab(
ronw@660 139 "long_test", kNumSamples, kNumEars, kNumChannels, kSampleRate);
alexbrandmeyer@626 140 }