blob: c3c413e83e3e0270021635a68caf66e305d1be22 [file] [log] [blame]
// Copyright 2016 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdlib.h>
#include <iostream>
#include "include/connector.h"
#include "include/evaluator.h"
#include "include/param_config.h"
#include "include/frame_generator.h"
using autotest_client::audio::Connector;
using autotest_client::audio::Evaluator;
using autotest_client::audio::FrameGenerator;
using autotest_client::audio::ParamConfig;
using autotest_client::audio::PlayClient;
using autotest_client::audio::RecordClient;
// Randomly picks an integer from the given range [min, max],
// including both end points.
inline int RandomPick(int min, int max) {
if (min > max) {
std::cerr << "Range error: min > max" << std::endl;
assert(false);
}
static unsigned int seed = time(NULL) + getpid();
return (rand_r(&seed) % (max - min + 1)) + min;
}
// Controls the main process of audiofuntest.
void ControlLoop(const ParamConfig &config,
Evaluator *evaluator,
RecordClient *recorder,
FrameGenerator *generator,
const int min_frequency = 4000,
const int max_frequency = 10000) {
const double frequency_resolution =
static_cast<double>(config.sample_rate) / config.fft_size;
const int min_bin = min_frequency / frequency_resolution;
const int max_bin = max_frequency / frequency_resolution;
vector<int> passes(config.num_mic_channels);
vector<bool> single_round_pass(config.num_mic_channels);
for (int round = 1; round <= config.test_rounds; ++round) {
std::fill(single_round_pass.begin(), single_round_pass.end(), false);
int bin = RandomPick(min_bin, max_bin);
double frequency = bin * frequency_resolution;
// Sets the frequency to be generated.
generator->SetFrequency(frequency);
int trial = evaluator->Evaluate(recorder, bin, &single_round_pass);
for (int chn = 0; chn < config.num_mic_channels; ++chn) {
if (single_round_pass[chn]) {
++passes[chn];
}
}
generator->SetStopPlayTone();
if (config.verbose) {
std::cout << "Frequency: " << frequency
<< " trial: " << trial << endl;
}
for (auto c : config.active_mic_channels) {
const char *res = single_round_pass[c] ? "[O]" : "[X]";
std::cout << (res)
<< " channel = " << c
<< ", success = " << passes[c]
<< ", fail = " << round - passes[c]
<< std::setprecision(4)
<< ", rate = "
<< 100.0 * passes[c] / round << "%\n";
}
std::cout << std::endl;
}
}
int main(int argc, char *argv[]) {
// Parses configuration.
ParamConfig config;
if (!config.ParseOptions(argc, argv)) {
config.PrintUsage(&std::cout, argv[0]);
return 0;
}
config.Print(&std::cout);
// Main role initialization.
FrameGenerator generator(config);
PlayClient player(config);
player.InitProcess(config.is_logging);
RecordClient recorder(config);
recorder.InitProcess(config.is_logging);
Evaluator evaluator(config);
generator.PlayTo(&player);
// Starts evaluation.
ControlLoop(config, &evaluator, &recorder, &generator);
// Terminates and cleans up.
recorder.Terminate();
// Stops generator before player to
// avoid sending tones to closed pipe.
generator.Stop();
player.Terminate();
return 0;
}