Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Unified Diff: webrtc/modules/audio_processing/test/fake_recording_device.cc

Issue 2834643002: audioproc_f with simulated mic analog gain (Closed)
Patch Set: AEC dump + fake rec device bugfix Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/test/fake_recording_device.cc
diff --git a/webrtc/modules/audio_processing/test/fake_recording_device.cc b/webrtc/modules/audio_processing/test/fake_recording_device.cc
new file mode 100644
index 0000000000000000000000000000000000000000..67ba34a3901e4b5fcd296683d8612625f8b9fbed
--- /dev/null
+++ b/webrtc/modules/audio_processing/test/fake_recording_device.cc
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2017 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 "webrtc/modules/audio_processing/test/fake_recording_device.h"
+
+#include <algorithm>
+
+#include "webrtc/rtc_base/logging.h"
+#include "webrtc/rtc_base/ptr_util.h"
+
+namespace webrtc {
+namespace test {
+
+namespace {
+
+constexpr int16_t kInt16SampleMin = -32768;
+constexpr int16_t kInt16SampleMax = 32767;
+constexpr float kFloatSampleMin = -32768.f;
+constexpr float kFloatSampleMax = 32767.0f;
+
+} // namespace
+
+// Abstract class for the different fake recording devices.
+class FakeRecordingDeviceWorker {
+ public:
+ explicit FakeRecordingDeviceWorker(const int initial_mic_level)
+ : mic_level_(initial_mic_level) {}
+ int mic_level() const { return mic_level_; }
+ void set_mic_level(const int level) { mic_level_ = level; }
+ void set_undo_mic_level(const rtc::Optional<int> level) {
+ undo_mic_level_ = level;
+ }
+ virtual ~FakeRecordingDeviceWorker() = default;
+ virtual void ModifyBufferInt16(AudioFrame* buffer) = 0;
+ virtual void ModifyBufferFloat(ChannelBuffer<float>* buffer) = 0;
+
+ protected:
+ // Mic level to simulate.
+ int mic_level_;
+ // Optional mic level to undo.
+ rtc::Optional<int> undo_mic_level_;
+};
+
+namespace {
+
+// Identity fake recording device. The samples are not modified, which is
+// equivalent to a constant gain curve at 1.0 - only used for testing.
+class FakeRecordingDeviceIdentity final : public FakeRecordingDeviceWorker {
+ public:
+ explicit FakeRecordingDeviceIdentity(const int initial_mic_level)
+ : FakeRecordingDeviceWorker(initial_mic_level) {}
+ ~FakeRecordingDeviceIdentity() override = default;
+ void ModifyBufferInt16(AudioFrame* buffer) override {}
+ void ModifyBufferFloat(ChannelBuffer<float>* buffer) override {}
+};
+
+// Linear fake recording device. The gain curve is a linear function mapping the
+// mic levels range [0, 255] to [0.0, 1.0].
+class FakeRecordingDeviceLinear final : public FakeRecordingDeviceWorker {
+ public:
+ explicit FakeRecordingDeviceLinear(const int initial_mic_level)
+ : FakeRecordingDeviceWorker(initial_mic_level) {}
+ ~FakeRecordingDeviceLinear() override = default;
+ void ModifyBufferInt16(AudioFrame* buffer) override {
+ const size_t number_of_samples =
+ buffer->samples_per_channel_ * buffer->num_channels_;
+ RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples);
peah-webrtc 2017/09/15 09:36:20 Is this DCHECK really needed? since both samples_p
AleBzk 2017/09/22 12:33:56 Done.
+ int16_t* data = buffer->mutable_data();
+ for (size_t i = 0; i < number_of_samples; ++i) {
+ const float sample_f = data[i];
peah-webrtc 2017/09/15 09:36:20 Why store data[i] in a local variable? It should b
peah-webrtc 2017/09/15 09:36:21 sample_f -> sample. No need to specify the type in
AleBzk 2017/09/22 12:33:55 Acknowledged.
AleBzk 2017/09/22 12:33:56 Done.
+ if (undo_mic_level_ && *undo_mic_level_ > 0) {
+ // Virtually restore the unmodified microphone level.
+ data[i] = std::max(kInt16SampleMin,
+ std::min(kInt16SampleMax,
+ static_cast<int16_t>(sample_f * mic_level_ /
+ *undo_mic_level_)));
+ } else {
+ // Simulate the mic gain only.
+ data[i] = std::max(
+ kInt16SampleMin,
+ std::min(kInt16SampleMax,
+ static_cast<int16_t>(sample_f * mic_level_ / 255.0f)));
+ }
+ }
+ }
+ void ModifyBufferFloat(ChannelBuffer<float>* buffer) override {
+ for (size_t c = 0; c < buffer->num_channels(); ++c) {
+ for (size_t i = 0; i < buffer->num_frames(); ++i) {
+ if (undo_mic_level_ && *undo_mic_level_ > 0) {
+ // Virtually restore the unmodified microphone level.
+ buffer->channels()[c][i] = std::max(
+ kFloatSampleMin,
+ std::min(kFloatSampleMax, buffer->channels()[c][i] * mic_level_ /
+ *undo_mic_level_));
+ } else {
+ // Simulate the mic gain only.
+ buffer->channels()[c][i] =
+ std::max(kFloatSampleMin,
+ std::min(kFloatSampleMax, buffer->channels()[c][i] *
+ mic_level_ / 255.0f));
+ }
+ }
+ }
+ }
+};
+
+} // namespace
+
+FakeRecordingDevice::FakeRecordingDevice(int initial_mic_level,
+ int device_kind) {
+ switch (device_kind) {
+ case 0:
+ worker_ = rtc::MakeUnique<FakeRecordingDeviceIdentity>(initial_mic_level);
+ break;
+ case 1:
+ worker_ = rtc::MakeUnique<FakeRecordingDeviceLinear>(initial_mic_level);
+ break;
+ default:
+ RTC_NOTREACHED();
+ break;
+ }
+}
+
+FakeRecordingDevice::~FakeRecordingDevice() = default;
+
+int FakeRecordingDevice::MicLevel() const {
+ RTC_DCHECK(worker_);
peah-webrtc 2017/09/15 09:36:20 This should probably be a CHECK, since it is test
AleBzk 2017/09/22 12:33:56 Fixed this and all the other DCHECKs. Thanks.
+ return worker_->mic_level();
+}
+
+void FakeRecordingDevice::SetMicLevel(const int level) {
+ RTC_DCHECK(worker_);
+ if (level != worker_->mic_level())
+ LOG(LS_INFO) << "simulate mic level update: " << level;
peah-webrtc 2017/09/15 09:36:21 simulate -> Simulate
AleBzk 2017/09/22 12:33:55 Done.
+ worker_->set_mic_level(level);
+}
+
+void FakeRecordingDevice::SetUndoMicLevel(const rtc::Optional<int> level) {
+ RTC_DCHECK(worker_);
+ // TODO(alessiob): The behavior with undo level equal to zero is not clear yet
+ // and will be defined in future CLs once more FakeRecordingDeviceWorker
+ // implementations need to be added.
+ RTC_CHECK(!level || *level > 0) << "Zero undo mic level is unsupported";
+ worker_->set_undo_mic_level(level);
+}
+
+void FakeRecordingDevice::SimulateAnalogGain(AudioFrame* buffer) {
+ RTC_DCHECK(worker_);
peah-webrtc 2017/09/15 09:36:20 This should probably be a CHECK, since it is test
AleBzk 2017/09/22 12:33:56 Done.
+ worker_->ModifyBufferInt16(buffer);
+}
+
+void FakeRecordingDevice::SimulateAnalogGain(ChannelBuffer<float>* buffer) {
+ RTC_DCHECK(worker_);
peah-webrtc 2017/09/15 09:36:21 This should probably be a CHECK, since it is test
AleBzk 2017/09/22 12:33:55 Done.
+ worker_->ModifyBufferFloat(buffer);
+}
+
+} // namespace test
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698