audiofuntest: Add option to evaluate power level
BUG=b:178681150
TEST=emerge-zork audiofuntest;
manually test on DUT;
Change-Id: If753c82b5dbc2dbd7852b4e55c7d8b2c37130880
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/audiotest/+/2928885
Commit-Queue: Gene Chang <genechang@google.com>
Tested-by: Gene Chang <genechang@google.com>
Auto-Submit: Gene Chang <genechang@google.com>
Reviewed-by: Pin-yen Lin <treapking@chromium.org>
Reviewed-by: Yu-Hsuan Hsu <yuhsuan@chromium.org>
diff --git a/include/common.h b/include/common.h
index 2fdb772..b5cb8b7 100644
--- a/include/common.h
+++ b/include/common.h
@@ -47,6 +47,7 @@
: allowed_delay_sec(1.5),
fft_size(2048u),
match_window_size(7),
+ power_threshold(0.01),
confidence_threshold(3),
sample_rate(64000),
sample_format(SampleFormat::kPcmS16),
@@ -64,6 +65,7 @@
double allowed_delay_sec;
int fft_size;
int match_window_size;
+ double power_threshold;
double confidence_threshold;
std::string player_command;
std::string player_fifo;
diff --git a/include/evaluator.h b/include/evaluator.h
index b6b5322..159cbfc 100644
--- a/include/evaluator.h
+++ b/include/evaluator.h
@@ -40,6 +40,7 @@
std::unique_ptr<uint8_t[]> buffer_;
size_t buf_size_;
+ double power_threshold_;
double confidence_threshold_;
int max_trial_;
diff --git a/src/audiofuntest.cc b/src/audiofuntest.cc
index 0bda5fd..f1b434e 100644
--- a/src/audiofuntest.cc
+++ b/src/audiofuntest.cc
@@ -16,33 +16,34 @@
#include "include/sample_format.h"
#include "include/tone_generators.h"
-constexpr static const char *short_options =
- "a:m:d:n:o:w:P:f:R:F:r:t:c:C:T:l:g:i:x:hv";
+constexpr static const char* short_options =
+ "a:m:d:n:o:w:p:P:f:R:F:r:t:c:C:T:l:g:i:x:hv";
constexpr static const struct option long_options[] = {
- {"active-speaker-channels", 1, NULL, 'a'},
- {"active-mic-channels", 1, NULL, 'm'},
- {"allowed-delay", 1, NULL, 'd'},
- {"fft-size", 1, NULL, 'n'},
- {"confidence-threshold", 1, NULL, 'o'},
- {"match-window-size", 1, NULL, 'w'},
- {"player-command", 1, NULL, 'P'},
- {"player-fifo", 1, NULL, 'f'},
- {"recorder-command", 1, NULL, 'R'},
- {"recorder-fifo", 1, NULL, 'F'},
- {"sample-rate", 1, NULL, 'r'},
- {"sample-format", 1, NULL, 't'},
- {"num-mic-channels", 1, NULL, 'c'},
- {"num-speaker-channels", 1, NULL, 'C'},
- {"test-rounds", 1, NULL, 'T'},
- {"tone-length", 1, NULL, 'l'},
- {"volume-gain", 1, NULL, 'g'},
- {"min-frequency", 1, NULL, 'i'},
- {"max-frequency", 1, NULL, 'x'},
+ {"active-speaker-channels", 1, NULL, 'a'},
+ {"active-mic-channels", 1, NULL, 'm'},
+ {"allowed-delay", 1, NULL, 'd'},
+ {"fft-size", 1, NULL, 'n'},
+ {"power-threshold", 1, NULL, 'p'},
+ {"confidence-threshold", 1, NULL, 'o'},
+ {"match-window-size", 1, NULL, 'w'},
+ {"player-command", 1, NULL, 'P'},
+ {"player-fifo", 1, NULL, 'f'},
+ {"recorder-command", 1, NULL, 'R'},
+ {"recorder-fifo", 1, NULL, 'F'},
+ {"sample-rate", 1, NULL, 'r'},
+ {"sample-format", 1, NULL, 't'},
+ {"num-mic-channels", 1, NULL, 'c'},
+ {"num-speaker-channels", 1, NULL, 'C'},
+ {"test-rounds", 1, NULL, 'T'},
+ {"tone-length", 1, NULL, 'l'},
+ {"volume-gain", 1, NULL, 'g'},
+ {"min-frequency", 1, NULL, 'i'},
+ {"max-frequency", 1, NULL, 'x'},
- // Other helper args.
- {"help", 0, NULL, 'h'},
- {"verbose", 0, NULL, 'v'},
+ // Other helper args.
+ {"help", 0, NULL, 'h'},
+ {"verbose", 0, NULL, 'v'},
};
// Parse the sample format. The input should be one of the string in
@@ -96,6 +97,9 @@
return false;
}
break;
+ case 'p':
+ config->power_threshold = atof(optarg);
+ break;
case 'P':
config->player_command = std::string(optarg);
break;
@@ -214,6 +218,11 @@
" Also, fftsize needs to be power of 2"
"(def %d)\n", default_config.fft_size);
fprintf(fd,
+ "\t-p, --power-threshold:\n"
+ "\t\tThreshold of RMS value to pass evaluation "
+ "(def %.4f)\n",
+ default_config.power_threshold);
+ fprintf(fd,
"\t-o, --confidence-threshold:\n"
"\t\tThreshold of accumulated confidence to pass evaluation "
"(def %.4f)\n", default_config.confidence_threshold);
diff --git a/src/evaluator.cc b/src/evaluator.cc
index 6c424b6..ec7d6ed 100644
--- a/src/evaluator.cc
+++ b/src/evaluator.cc
@@ -78,7 +78,7 @@
} // namespace
-Evaluator::Evaluator(const AudioFunTestConfig &config)
+Evaluator::Evaluator(const AudioFunTestConfig& config)
: filter_(config.match_window_size),
half_window_size_(config.match_window_size / 2),
num_channels_(config.num_mic_channels),
@@ -86,6 +86,7 @@
format_(config.sample_format),
sample_rate_(config.sample_rate),
bin_(config.match_window_size),
+ power_threshold_(config.power_threshold),
confidence_threshold_(config.confidence_threshold),
verbose_(config.verbose) {
// Initializes original expected filter.
@@ -146,6 +147,24 @@
double Evaluator::EstimateChannel(
std::vector<double> *data, int center_bin) {
+ // Calculate RMS before FFT
+ // The |data| here is already formatted as double sized to store the result
+ // (read, imaginary) from FFT.
+ int data_size = data->size() / 2;
+ double rms = 0.0;
+ for (int t = 0; t < data_size; ++t) {
+ const double amplitude = (*data)[2 * t];
+ rms += amplitude * amplitude;
+ }
+ rms = sqrt(rms / data_size);
+ if (verbose_)
+ printf("rms: %0.4f\n", rms);
+
+ if (rms < power_threshold_) {
+ perror("The RMS level is too low.");
+ return 0.0;
+ }
+
FFT(data);
double confidence = 0.0, mean = 0.0, sigma = 0.0;