OLD | NEW |
---|---|
(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; | |
peah-webrtc
2017/08/18 04:27:00
The range for the float values inside APM is [-327
| |
26 constexpr float kFloatSampleMax = 1.0f; | |
27 | |
28 } // namespace | |
29 | |
30 // Abstract class for the different fake recording devices. | |
31 class FakeRecordingDeviceWorker { | |
32 public: | |
33 FakeRecordingDeviceWorker(const int& mic_level, | |
34 const rtc::Optional<int>& undo_mic_level) | |
35 : mic_level_(mic_level), undo_mic_level_(undo_mic_level) {} | |
36 virtual ~FakeRecordingDeviceWorker() = default; | |
37 virtual void ModifyBufferInt16(AudioFrame* buffer) = 0; | |
38 virtual void ModifyBufferFloat(ChannelBuffer<float>* buffer) = 0; | |
39 | |
40 protected: | |
41 const int& mic_level_; | |
42 const rtc::Optional<int>& undo_mic_level_; | |
peah-webrtc
2017/08/18 04:27:00
As discussed offline, please remove this as a refe
| |
43 }; | |
44 | |
45 namespace { | |
46 | |
47 // Identity fake recording device. The samples are not modified, which is | |
48 // equivalent to a constant gain curve at 1.0 - only used for testing. | |
49 class FakeRecordingDeviceIdentity final : public FakeRecordingDeviceWorker { | |
50 public: | |
51 FakeRecordingDeviceIdentity(const int& mic_level, | |
52 const rtc::Optional<int>& undo_mic_level) | |
53 : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {} | |
54 ~FakeRecordingDeviceIdentity() override = default; | |
55 void ModifyBufferInt16(AudioFrame* buffer) override {} | |
56 void ModifyBufferFloat(ChannelBuffer<float>* buffer) override {} | |
57 }; | |
58 | |
59 // Linear fake recording device. The gain curve is a linear function mapping the | |
60 // mic levels range [0, 255] to [0.0, 1.0]. | |
peah-webrtc
2017/08/18 04:27:00
Since you specify the allowed range for the mic le
| |
61 class FakeRecordingDeviceLinear final : public FakeRecordingDeviceWorker { | |
62 public: | |
63 FakeRecordingDeviceLinear(const int& mic_level, | |
64 const rtc::Optional<int>& undo_mic_level) | |
65 : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {} | |
66 ~FakeRecordingDeviceLinear() override = default; | |
67 void ModifyBufferInt16(AudioFrame* buffer) override { | |
peah-webrtc
2017/08/18 04:27:00
Since you add implementations within the class def
| |
68 const size_t number_of_samples = | |
69 buffer->samples_per_channel_ * buffer->num_channels_; | |
70 RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples); | |
71 int16_t* data = buffer->mutable_data(); | |
72 for (size_t i = 0; i < number_of_samples; ++i) { | |
73 const float sample_f = data[i]; | |
74 if (undo_mic_level_ && *undo_mic_level_ > 0) { | |
peah-webrtc
2017/08/18 04:27:00
Regarding *undo_mic_level_ > 0, please see comment
| |
75 // Virtually restore the unmodified microphone level. | |
76 data[i] = std::max(kInt16SampleMin, | |
77 std::min(kInt16SampleMax, | |
78 static_cast<int16_t>(sample_f * mic_level_ / | |
79 *undo_mic_level_))); | |
80 } else { | |
81 // Simulate the mic gain only. | |
82 data[i] = std::max( | |
83 kInt16SampleMin, | |
84 std::min(kInt16SampleMax, | |
85 static_cast<int16_t>(sample_f * mic_level_ / 255.0f))); | |
86 } | |
87 } | |
88 } | |
89 void ModifyBufferFloat(ChannelBuffer<float>* buffer) override { | |
90 for (size_t c = 0; c < buffer->num_channels(); ++c) { | |
91 for (size_t i = 0; i < buffer->num_frames(); ++i) { | |
92 if (undo_mic_level_ && *undo_mic_level_ > 0) { | |
peah-webrtc
2017/08/18 04:27:00
why do you need to check for *undo_mic_level_ > 0
| |
93 // Virtually restore the unmodified microphone level. | |
94 buffer->channels()[c][i] = std::max( | |
95 kFloatSampleMin, | |
96 std::min(kFloatSampleMax, buffer->channels()[c][i] * mic_level_ / | |
97 *undo_mic_level_)); | |
98 } else { | |
99 // Simulate the mic gain only. | |
100 buffer->channels()[c][i] = | |
101 std::max(kFloatSampleMin, | |
102 std::min(kFloatSampleMax, buffer->channels()[c][i] * | |
103 mic_level_ / 255.0f)); | |
104 } | |
105 } | |
106 } | |
107 } | |
108 }; | |
109 | |
110 } // namespace | |
111 | |
112 FakeRecordingDevice::FakeRecordingDevice(int initial_mic_level, int device_kind) | |
113 : mic_level_(initial_mic_level) { | |
114 switch (device_kind) { | |
115 case 0: | |
116 worker_ = rtc::MakeUnique<FakeRecordingDeviceIdentity>(mic_level_, | |
117 undo_mic_level_); | |
118 break; | |
119 case 1: | |
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 | |
OLD | NEW |