
Changes differing from https://webrtc-codereview.appspot.com/37859004: * I put the include_tests==1 stuff of audio_coding.gypi in its own audio_coding_tests.gypi file, including the Android and isolate targets which were incorrectly located in the previous CL * I moved the bwe utilities in remote_bitrate_estimator.gypi into include_tests==1 since they depend on test.gyp after I cleaned up the duplicated inclusion of rtp_file_reader.cc R=stefan@webrtc.org TBR=tina.legrand@webrtc.org TESTED=Passing gyp and compile using: webrtc/build/gyp_webrtc -Dinclude_tests=1 webrtc/build/gyp_webrtc -Dinclude_tests=0 I also setup a Chromium checkout with my checkout mounted in third_party/webrtc and ran build/gyp_chromium successfully. BUG=4185 Review URL: https://webrtc-codereview.appspot.com/33159004 Cr-Commit-Position: refs/heads/master@{#8205} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8205 4adac7df-926f-26a2-2b94-8c16560cd09d
156 lines
5.5 KiB
C++
156 lines
5.5 KiB
C++
/*
|
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "gflags/gflags.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "webrtc/modules/audio_processing/agc/agc.h"
|
|
#include "webrtc/modules/audio_processing/agc/utility.h"
|
|
#include "webrtc/modules/audio_processing/include/audio_processing.h"
|
|
#include "webrtc/modules/interface/module_common_types.h"
|
|
#include "webrtc/system_wrappers/interface/logging.h"
|
|
#include "webrtc/test/testsupport/trace_to_stderr.h"
|
|
#include "webrtc/tools/agc/agc_manager.h"
|
|
#include "webrtc/tools/agc/test_utils.h"
|
|
#include "webrtc/voice_engine/include/mock/fake_voe_external_media.h"
|
|
#include "webrtc/voice_engine/include/mock/mock_voe_volume_control.h"
|
|
|
|
DEFINE_string(in, "in.pcm", "input filename");
|
|
DEFINE_string(out, "out.pcm", "output filename");
|
|
DEFINE_int32(rate, 16000, "sample rate in Hz");
|
|
DEFINE_int32(channels, 1, "number of channels");
|
|
DEFINE_int32(level, -18, "target level in RMS dBFs [-100, 0]");
|
|
DEFINE_bool(limiter, true, "enable a limiter for the compression stage");
|
|
DEFINE_int32(cmp_level, 2, "target level in dBFs for the compression stage");
|
|
DEFINE_int32(mic_gain, 80, "range of gain provided by the virtual mic in dB");
|
|
DEFINE_int32(gain_offset, 0,
|
|
"an amount (in dB) to add to every entry in the gain map");
|
|
DEFINE_string(gain_file, "",
|
|
"filename providing a mic gain mapping. The file should be text containing "
|
|
"a (floating-point) gain entry in dBFs per line corresponding to levels "
|
|
"from 0 to 255.");
|
|
|
|
using ::testing::_;
|
|
using ::testing::ByRef;
|
|
using ::testing::DoAll;
|
|
using ::testing::Mock;
|
|
using ::testing::Return;
|
|
using ::testing::SaveArg;
|
|
using ::testing::SetArgReferee;
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
const char kUsage[] = "\nProcess an audio file to simulate an analog agc.";
|
|
|
|
void ReadGainMapFromFile(FILE* file, int offset, int gain_map[256]) {
|
|
for (int i = 0; i < 256; ++i) {
|
|
float gain = 0;
|
|
ASSERT_EQ(1, fscanf(file, "%f", &gain));
|
|
gain_map[i] = std::floor(gain + 0.5);
|
|
}
|
|
|
|
// Adjust from dBFs to gain in dB. We assume that level 127 provides 0 dB
|
|
// gain. This corresponds to the interpretation in MicLevel2Gain().
|
|
const int midpoint = gain_map[127];
|
|
printf("Gain map\n");
|
|
for (int i = 0; i < 256; ++i) {
|
|
gain_map[i] += offset - midpoint;
|
|
if (i % 5 == 0) {
|
|
printf("%d: %d dB\n", i, gain_map[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CalculateGainMap(int gain_range_db, int offset, int gain_map[256]) {
|
|
printf("Gain map\n");
|
|
for (int i = 0; i < 256; ++i) {
|
|
gain_map[i] = std::floor(MicLevel2Gain(gain_range_db, i) + 0.5) + offset;
|
|
if (i % 5 == 0) {
|
|
printf("%d: %d dB\n", i, gain_map[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RunAgc() {
|
|
test::TraceToStderr trace_to_stderr(true);
|
|
FILE* in_file = fopen(FLAGS_in.c_str(), "rb");
|
|
ASSERT_TRUE(in_file != NULL);
|
|
FILE* out_file = fopen(FLAGS_out.c_str(), "wb");
|
|
ASSERT_TRUE(out_file != NULL);
|
|
|
|
int gain_map[256];
|
|
if (FLAGS_gain_file != "") {
|
|
FILE* gain_file = fopen(FLAGS_gain_file.c_str(), "rt");
|
|
ASSERT_TRUE(gain_file != NULL);
|
|
ReadGainMapFromFile(gain_file, FLAGS_gain_offset, gain_map);
|
|
fclose(gain_file);
|
|
} else {
|
|
CalculateGainMap(FLAGS_mic_gain, FLAGS_gain_offset, gain_map);
|
|
}
|
|
|
|
FakeVoEExternalMedia media;
|
|
MockVoEVolumeControl volume;
|
|
Agc* agc = new Agc;
|
|
AudioProcessing* audioproc = AudioProcessing::Create();
|
|
ASSERT_TRUE(audioproc != NULL);
|
|
AgcManager manager(&media, &volume, agc, audioproc);
|
|
|
|
int mic_level = 128;
|
|
int last_mic_level = mic_level;
|
|
EXPECT_CALL(volume, GetMicVolume(_))
|
|
.WillRepeatedly(DoAll(SetArgReferee<0>(ByRef(mic_level)), Return(0)));
|
|
EXPECT_CALL(volume, SetMicVolume(_))
|
|
.WillRepeatedly(DoAll(SaveArg<0>(&mic_level), Return(0)));
|
|
|
|
manager.Enable(true);
|
|
ASSERT_EQ(0, agc->set_target_level_dbfs(FLAGS_level));
|
|
const AudioProcessing::Error kNoErr = AudioProcessing::kNoError;
|
|
GainControl* gctrl = audioproc->gain_control();
|
|
ASSERT_EQ(kNoErr, gctrl->set_target_level_dbfs(FLAGS_cmp_level));
|
|
ASSERT_EQ(kNoErr, gctrl->enable_limiter(FLAGS_limiter));
|
|
|
|
AudioFrame frame;
|
|
frame.num_channels_ = FLAGS_channels;
|
|
frame.sample_rate_hz_ = FLAGS_rate;
|
|
frame.samples_per_channel_ = FLAGS_rate / 100;
|
|
const size_t frame_length = frame.samples_per_channel_ * FLAGS_channels;
|
|
size_t sample_count = 0;
|
|
while (fread(frame.data_, sizeof(int16_t), frame_length, in_file) ==
|
|
frame_length) {
|
|
SimulateMic(gain_map, mic_level, last_mic_level, &frame);
|
|
last_mic_level = mic_level;
|
|
media.CallProcess(kRecordingAllChannelsMixed, frame.data_,
|
|
frame.samples_per_channel_, FLAGS_rate, FLAGS_channels);
|
|
ASSERT_EQ(frame_length,
|
|
fwrite(frame.data_, sizeof(int16_t), frame_length, out_file));
|
|
sample_count += frame_length;
|
|
trace_to_stderr.SetTimeSeconds(static_cast<float>(sample_count) /
|
|
FLAGS_channels / FLAGS_rate);
|
|
}
|
|
fclose(in_file);
|
|
fclose(out_file);
|
|
EXPECT_CALL(volume, Release());
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace webrtc
|
|
|
|
int main(int argc, char* argv[]) {
|
|
google::SetUsageMessage(webrtc::kUsage);
|
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
|
webrtc::RunAgc();
|
|
return 0;
|
|
}
|