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

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: Merge + comments addressed Created 3 years, 5 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/base/logging.h"
16 #include "webrtc/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 = -1.0f;
26 constexpr float kFloatSampleMax = 1.0f;
27
28 int16_t ClipSampleFloatToInt16(float sample) {
29 return std::max(std::min(sample, static_cast<float>(kInt16SampleMax)),
30 static_cast<float>(kInt16SampleMin));
31 }
32
33 float ClipSampleFloatToFloat(float sample) {
34 return std::max(std::min(sample, kFloatSampleMax), kFloatSampleMin);
35 }
AleBzk 2017/07/26 13:42:30 Removed since these functions may confuse the read
36
37 } // namespace
38
39 // Abstract class for the different fake recording devices.
40 class FakeRecordingDeviceWorker {
41 public:
42 FakeRecordingDeviceWorker(const int& mic_level,
43 const rtc::Optional<int>& undo_mic_level)
44 : mic_level_(mic_level), undo_mic_level_(undo_mic_level) {}
45 virtual ~FakeRecordingDeviceWorker() = default;
46 virtual void ModifyBufferInt16(AudioFrame* buffer) = 0;
47 virtual void ModifyBufferFloat(ChannelBuffer<float>* buffer) = 0;
48
49 protected:
50 const int& mic_level_;
51 const rtc::Optional<int>& undo_mic_level_;
52 };
53
54 namespace {
55
56 // Identity fake recording device. The samples are not modified, which is
57 // equivalent to a constant gain curve at 1.0 - only used for testing.
58 class FakeRecordingDeviceIdentity final : public FakeRecordingDeviceWorker {
59 public:
60 FakeRecordingDeviceIdentity(const int& mic_level,
61 const rtc::Optional<int>& undo_mic_level)
62 : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {}
63 ~FakeRecordingDeviceIdentity() override = default;
64 void ModifyBufferInt16(AudioFrame* buffer) override {}
65 void ModifyBufferFloat(ChannelBuffer<float>* buffer) override {}
66 };
67
68 // Linear fake recording device. The gain curve is a linear function mapping the
69 // mic levels range [0, 255] to [0.0, 1.0].
70 class FakeRecordingDeviceLinear final : public FakeRecordingDeviceWorker {
71 public:
72 FakeRecordingDeviceLinear(const int& mic_level,
73 const rtc::Optional<int>& undo_mic_level)
74 : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {}
75 ~FakeRecordingDeviceLinear() override = default;
76 void ModifyBufferInt16(AudioFrame* buffer) override {
77 const size_t number_of_samples =
78 buffer->samples_per_channel_ * buffer->num_channels_;
79 RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples);
80 int16_t* data = buffer->mutable_data();
81 for (size_t i = 0; i < number_of_samples; ++i) {
82 const float sample_f = data[i];
83 if (undo_mic_level_ && *undo_mic_level_ > 0) {
84 // Virtually restore the unmodified microphone level.
85 data[i] =
86 ClipSampleFloatToInt16(sample_f * mic_level_ / *undo_mic_level_);
87 } else {
88 // Simulate the mic gain only.
89 data[i] = ClipSampleFloatToInt16(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] = ClipSampleFloatToFloat(
99 buffer->channels()[c][i] * mic_level_ / *undo_mic_level_);
100 } else {
101 // Simulate the mic gain only.
102 buffer->channels()[c][i] = ClipSampleFloatToFloat(
103 buffer->channels()[c][i] * mic_level_ / 255.0f);
104 }
105 }
106 }
107 }
108 };
109
110 } // namespace
111
112 FakeRecordingDevice::FakeRecordingDevice(int initial_mic_level, DeviceKind kind)
peah-webrtc 2017/06/29 22:04:00 Having seen the usage of the constructor, I defini
113 : mic_level_(initial_mic_level) {
114 switch (kind) {
115 case FakeRecordingDevice::DeviceKind::IDENTITY:
116 worker_ = rtc::MakeUnique<FakeRecordingDeviceIdentity>(mic_level_,
117 undo_mic_level_);
118 break;
119 case FakeRecordingDevice::DeviceKind::LINEAR:
120 worker_ = rtc::MakeUnique<FakeRecordingDeviceLinear>(mic_level_,
121 undo_mic_level_);
122 break;
123 default:
124 RTC_NOTREACHED();
125 break;
126 }
127 }
128
129 FakeRecordingDevice::~FakeRecordingDevice() = default;
130
131 void FakeRecordingDevice::SimulateAnalogGain(AudioFrame* buffer) {
132 RTC_DCHECK(worker_);
133 worker_->ModifyBufferInt16(buffer);
134 }
135
136 void FakeRecordingDevice::SimulateAnalogGain(ChannelBuffer<float>* buffer) {
137 RTC_DCHECK(worker_);
138 worker_->ModifyBufferFloat(buffer);
139 }
140
141 } // namespace test
142 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698