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

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

Issue 2834643002: audioproc_f with simulated mic analog gain (Closed)
Patch Set: fake rec device boilerplate reduced, aec dump simulated analog gain logic moved Created 3 years, 6 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..12fb23a4eb2e561241e9d05977e8d4f31dfb04d4
--- /dev/null
+++ b/webrtc/modules/audio_processing/test/fake_recording_device.cc
@@ -0,0 +1,138 @@
+/*
+ * 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/base/logging.h"
+#include "webrtc/base/ptr_util.h"
+
+namespace webrtc {
+namespace test {
+
+// Abstract class for the different fake recording devices.
peah-webrtc 2017/06/29 05:45:27 The scheme for the clipping and analog gain is qui
AleBzk 2017/06/29 11:43:35 Thanks for these concerns. First, to improve the
peah-webrtc 2017/06/29 22:03:59 With simpler implementation, I rather mean less ad
AleBzk 2017/07/26 13:42:30 I removed the hard clipping functions from the ano
+class FakeRecordingDeviceWorker {
+ private:
+ const int16_t kInt16SampleMin = -32768;
+ const int16_t kInt16SampleMax = 32767;
+ const float kFloatSampleMin = -1.0f;
+ const float kFloatSampleMax = 1.0f;
+ public:
+ FakeRecordingDeviceWorker(
+ const int& mic_level, const rtc::Optional<int>& undo_mic_level)
+ : mic_level_(mic_level), undo_mic_level_(undo_mic_level) {}
+ virtual ~FakeRecordingDeviceWorker() = default;
+ virtual void ModifySampleInt16(int16_t* sample) = 0;
+ virtual void ModifySampleFloat(float* sample) = 0;
+ protected:
+ int16_t ClipSampleInt16(int16_t sample) {
+ return std::max(std::min(sample, kInt16SampleMax), kInt16SampleMin);
+ }
+ float ClipSampleFloat(float sample) {
+ return std::max(std::min(sample, kFloatSampleMax), kFloatSampleMin);
+ }
+ const int& mic_level_;
+ const rtc::Optional<int>& undo_mic_level_;
+};
AleBzk 2017/06/22 10:16:01 This is the class to be implemented for each simul
+
+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:
+ FakeRecordingDeviceIdentity(
+ const int& mic_level, const rtc::Optional<int>& undo_mic_level)
+ : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {}
+ ~FakeRecordingDeviceIdentity() override = default;
+ void ModifySampleInt16(int16_t* sample) override {}
+ void ModifySampleFloat(float* sample) override {}
AleBzk 2017/06/22 10:16:01 This is a recording device that does nothing.
+};
+
+// 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:
+ FakeRecordingDeviceLinear(
+ const int& mic_level, const rtc::Optional<int>& undo_mic_level)
+ : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {}
+ ~FakeRecordingDeviceLinear() override = default;
+ void ModifySampleInt16(int16_t* sample) override {
+ float sample_f = static_cast<float>(*sample);
peah-webrtc 2017/06/29 05:45:27 You don't need to do the cast here.
AleBzk 2017/06/29 11:43:35 Done.
+
+ if (undo_mic_level_ && *undo_mic_level_ > 0) {
+ // Virtually restore the unmodified microphone level.
+ *sample = ClipSampleInt16(
+ sample_f * static_cast<float>(mic_level_) / static_cast<float>(
peah-webrtc 2017/06/29 05:45:27 There is a bug here I think. A float is passed to
peah-webrtc 2017/06/29 05:45:27 Same thing here, no casts are needed.
AleBzk 2017/06/29 11:43:35 Right, thanks. Using goma I missed the compiler wa
AleBzk 2017/06/29 11:43:36 Done.
+ *undo_mic_level_));
+ } else {
+ // Simulate the mic gain only.
+ *sample = ClipSampleInt16(
+ sample_f * static_cast<float>(mic_level_) / 255.0f);
+ }
+ }
+ void ModifySampleFloat(float* sample) override {
+ if (undo_mic_level_ && *undo_mic_level_ > 0) {
+ // Virtually restore the unmodified microphone level.
+ *sample = ClipSampleFloat(
+ *sample * static_cast<float>(mic_level_) / static_cast<float>(
peah-webrtc 2017/06/29 05:45:27 Are the static casts really needed? Since sample i
AleBzk 2017/06/29 11:43:35 Done.
+ *undo_mic_level_));
+ } else {
+ // Simulate the mic gain only.
+ *sample = ClipSampleFloat(
+ *sample * static_cast<float>(mic_level_) / 255.0f);
peah-webrtc 2017/06/29 05:45:27 The cast is not needed.
AleBzk 2017/06/29 11:43:36 Done.
+ }
+ }
+};
+
+} // namespace
+
+FakeRecordingDevice::FakeRecordingDevice(int initial_mic_level, DeviceKind kind)
+ : mic_level_(initial_mic_level) {
+ switch (kind) {
+ case FakeRecordingDevice::DeviceKind::IDENTITY:
+ worker_ = rtc::MakeUnique<FakeRecordingDeviceIdentity>(
+ mic_level_, undo_mic_level_);
+ break;
+ case FakeRecordingDevice::DeviceKind::LINEAR:
+ worker_ = rtc::MakeUnique<FakeRecordingDeviceLinear>(
+ mic_level_, undo_mic_level_);
+ break;
+ default:
+ RTC_NOTREACHED();
+ break;
+ }
+}
+
+FakeRecordingDevice::~FakeRecordingDevice() = default;
+
+void FakeRecordingDevice::SimulateAnalogGain(ChannelBuffer<float>* buffer) {
+ RTC_DCHECK(worker_);
+ size_t number_of_samples = buffer->num_frames();
+ for (size_t i = 0; i < buffer->num_channels(); ++i) {
+ std::for_each(buffer->channels()[i],
+ buffer->channels()[i] + number_of_samples,
+ [this](float& x) { worker_->ModifySampleFloat(&x); });
peah-webrtc 2017/06/29 05:45:27 Why not pass the whole vector into ModifySampleFlo
AleBzk 2017/06/29 11:43:35 Just wanted to decouple FakeRecordingDeviceWorker
peah-webrtc 2017/06/29 22:03:59 I'd say do this as simple as possible now, as you'
AleBzk 2017/07/26 13:42:30 Yup. Not sure if you've seen the latest PS before
+ }
+}
+
+void FakeRecordingDevice::SimulateAnalogGain(AudioFrame* buffer) {
+ RTC_DCHECK(worker_);
+ const size_t number_of_samples =
+ buffer->samples_per_channel_ * buffer->num_channels_;
+ RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples);
+ std::for_each(buffer->mutable_data(),
+ buffer->mutable_data() + number_of_samples,
+ [this](int16_t& x) { worker_->ModifySampleInt16(&x); });
peah-webrtc 2017/06/29 05:45:27 Why not just pass the whole vector into ModifySamp
AleBzk 2017/06/29 11:43:35 Addressed (see previous comment). Also good to cor
+}
+
+} // namespace test
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698