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

Side by Side Diff: webrtc/modules/audio_processing/test/fake_recording_device.cc

Issue 2834643002: audioproc_f with simulated mic analog gain (Closed)
Patch Set: minor changes Created 3 years, 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/audio_processing/test/fake_recording_device.h"
12
13 #include <algorithm>
14
15 #include "webrtc/rtc_base/logging.h"
16 #include "webrtc/rtc_base/ptr_util.h"
17
18 namespace webrtc {
19 namespace test {
20
21 namespace {
22
23 constexpr int16_t kInt16SampleMin = -32768;
24 constexpr int16_t kInt16SampleMax = 32767;
25 constexpr float kFloatSampleMin = -32768.f;
26 constexpr float kFloatSampleMax = 32767.0f;
27
28 } // namespace
29
30 // Abstract class for the different fake recording devices.
31 class FakeRecordingDeviceWorker {
32 public:
33 explicit FakeRecordingDeviceWorker(const int initial_mic_level)
34 : mic_level_(initial_mic_level) {}
35 int mic_level() const { return mic_level_; }
36 void set_mic_level(const int level) { mic_level_ = level; }
37 void set_undo_mic_level(const rtc::Optional<int> level) {
38 undo_mic_level_ = level;
39 }
40 virtual ~FakeRecordingDeviceWorker() = default;
41 virtual void ModifyBufferInt16(AudioFrame* buffer) = 0;
42 virtual void ModifyBufferFloat(ChannelBuffer<float>* buffer) = 0;
43
44 protected:
45 // Mic level to simulate.
46 int mic_level_;
47 // Optional mic level to undo.
48 rtc::Optional<int> undo_mic_level_;
49 };
50
51 namespace {
52
53 // Identity fake recording device. The samples are not modified, which is
54 // equivalent to a constant gain curve at 1.0 - only used for testing.
55 class FakeRecordingDeviceIdentity final : public FakeRecordingDeviceWorker {
56 public:
57 explicit FakeRecordingDeviceIdentity(const int initial_mic_level)
58 : FakeRecordingDeviceWorker(initial_mic_level) {}
59 ~FakeRecordingDeviceIdentity() override = default;
60 void ModifyBufferInt16(AudioFrame* buffer) override {}
61 void ModifyBufferFloat(ChannelBuffer<float>* buffer) override {}
62 };
63
64 // Linear fake recording device. The gain curve is a linear function mapping the
65 // mic levels range [0, 255] to [0.0, 1.0].
66 class FakeRecordingDeviceLinear final : public FakeRecordingDeviceWorker {
67 public:
68 explicit FakeRecordingDeviceLinear(const int initial_mic_level)
69 : FakeRecordingDeviceWorker(initial_mic_level) {}
70 ~FakeRecordingDeviceLinear() override = default;
71 void ModifyBufferInt16(AudioFrame* buffer) override {
72 const size_t number_of_samples =
73 buffer->samples_per_channel_ * buffer->num_channels_;
74 RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples);
75 int16_t* data = buffer->mutable_data();
76 for (size_t i = 0; i < number_of_samples; ++i) {
77 const float sample_f = data[i];
78 if (undo_mic_level_ && *undo_mic_level_ > 0) {
79 // Virtually restore the unmodified microphone level.
80 data[i] = std::max(kInt16SampleMin,
81 std::min(kInt16SampleMax,
82 static_cast<int16_t>(sample_f * mic_level_ /
83 *undo_mic_level_)));
84 } else {
85 // Simulate the mic gain only.
86 data[i] = std::max(
87 kInt16SampleMin,
88 std::min(kInt16SampleMax,
89 static_cast<int16_t>(sample_f * mic_level_ / 255.0f)));
90 }
91 }
92 }
93 void ModifyBufferFloat(ChannelBuffer<float>* buffer) override {
94 for (size_t c = 0; c < buffer->num_channels(); ++c) {
95 for (size_t i = 0; i < buffer->num_frames(); ++i) {
96 if (undo_mic_level_ && *undo_mic_level_ > 0) {
97 // Virtually restore the unmodified microphone level.
98 buffer->channels()[c][i] = std::max(
99 kFloatSampleMin,
100 std::min(kFloatSampleMax, buffer->channels()[c][i] * mic_level_ /
101 *undo_mic_level_));
102 } else {
103 // Simulate the mic gain only.
104 buffer->channels()[c][i] =
105 std::max(kFloatSampleMin,
106 std::min(kFloatSampleMax, buffer->channels()[c][i] *
107 mic_level_ / 255.0f));
108 }
109 }
110 }
111 }
112 };
113
114 } // namespace
115
116 FakeRecordingDevice::FakeRecordingDevice(int initial_mic_level,
117 int device_kind) {
118 switch (device_kind) {
119 case 0:
120 worker_ = rtc::MakeUnique<FakeRecordingDeviceIdentity>(initial_mic_level);
121 break;
122 case 1:
123 worker_ = rtc::MakeUnique<FakeRecordingDeviceLinear>(initial_mic_level);
124 break;
125 default:
126 RTC_NOTREACHED();
127 break;
128 }
129 }
130
131 FakeRecordingDevice::~FakeRecordingDevice() = default;
132
133 int FakeRecordingDevice::MicLevel() const {
134 RTC_DCHECK(worker_);
135 return worker_->mic_level();
136 }
137
138 void FakeRecordingDevice::SetMicLevel(const int level) {
139 RTC_DCHECK(worker_);
140 if (level != worker_->mic_level())
141 LOG(LS_INFO) << "simulate mic level update: " << level;
142 worker_->set_mic_level(level);
143 }
144
145 void FakeRecordingDevice::SetUndoMicLevel(const rtc::Optional<int> level) {
146 RTC_DCHECK(worker_);
147 // TODO(alessiob): The behavior with undo level equal to zero is not clear yet
148 // and will be defined in future CLs once more FakeRecordingDeviceWorker
149 // implementations need to be added.
150 RTC_CHECK(!level || *level > 0) << "Zero undo mic level is unsupported";
151 worker_->set_undo_mic_level(level);
152 }
153
154 void FakeRecordingDevice::SimulateAnalogGain(AudioFrame* buffer) {
155 RTC_DCHECK(worker_);
156 worker_->ModifyBufferInt16(buffer);
157 }
158
159 void FakeRecordingDevice::SimulateAnalogGain(ChannelBuffer<float>* buffer) {
160 RTC_DCHECK(worker_);
161 worker_->ModifyBufferFloat(buffer);
162 }
163
164 } // namespace test
165 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698