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 // 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
| |
22 class FakeRecordingDeviceWorker { | |
23 private: | |
24 const int16_t kInt16SampleMin = -32768; | |
25 const int16_t kInt16SampleMax = 32767; | |
26 const float kFloatSampleMin = -1.0f; | |
27 const float kFloatSampleMax = 1.0f; | |
28 public: | |
29 FakeRecordingDeviceWorker( | |
30 const int& mic_level, const rtc::Optional<int>& undo_mic_level) | |
31 : mic_level_(mic_level), undo_mic_level_(undo_mic_level) {} | |
32 virtual ~FakeRecordingDeviceWorker() = default; | |
33 virtual void ModifySampleInt16(int16_t* sample) = 0; | |
34 virtual void ModifySampleFloat(float* sample) = 0; | |
35 protected: | |
36 int16_t ClipSampleInt16(int16_t sample) { | |
37 return std::max(std::min(sample, kInt16SampleMax), kInt16SampleMin); | |
38 } | |
39 float ClipSampleFloat(float sample) { | |
40 return std::max(std::min(sample, kFloatSampleMax), kFloatSampleMin); | |
41 } | |
42 const int& mic_level_; | |
43 const rtc::Optional<int>& undo_mic_level_; | |
44 }; | |
AleBzk
2017/06/22 10:16:01
This is the class to be implemented for each simul
| |
45 | |
46 namespace { | |
47 | |
48 // Identity fake recording device. The samples are not modified, which is | |
49 // equivalent to a constant gain curve at 1.0 - only used for testing. | |
50 class FakeRecordingDeviceIdentity final : public FakeRecordingDeviceWorker { | |
51 public: | |
52 FakeRecordingDeviceIdentity( | |
53 const int& mic_level, const rtc::Optional<int>& undo_mic_level) | |
54 : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {} | |
55 ~FakeRecordingDeviceIdentity() override = default; | |
56 void ModifySampleInt16(int16_t* sample) override {} | |
57 void ModifySampleFloat(float* sample) override {} | |
AleBzk
2017/06/22 10:16:01
This is a recording device that does nothing.
| |
58 }; | |
59 | |
60 // Linear fake recording device. The gain curve is a linear function mapping the | |
61 // mic levels range [0, 255] to [0.0, 1.0]. | |
62 class FakeRecordingDeviceLinear final : public FakeRecordingDeviceWorker { | |
63 public: | |
64 FakeRecordingDeviceLinear( | |
65 const int& mic_level, const rtc::Optional<int>& undo_mic_level) | |
66 : FakeRecordingDeviceWorker(mic_level, undo_mic_level) {} | |
67 ~FakeRecordingDeviceLinear() override = default; | |
68 void ModifySampleInt16(int16_t* sample) override { | |
69 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.
| |
70 | |
71 if (undo_mic_level_ && *undo_mic_level_ > 0) { | |
72 // Virtually restore the unmodified microphone level. | |
73 *sample = ClipSampleInt16( | |
74 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.
| |
75 *undo_mic_level_)); | |
76 } else { | |
77 // Simulate the mic gain only. | |
78 *sample = ClipSampleInt16( | |
79 sample_f * static_cast<float>(mic_level_) / 255.0f); | |
80 } | |
81 } | |
82 void ModifySampleFloat(float* sample) override { | |
83 if (undo_mic_level_ && *undo_mic_level_ > 0) { | |
84 // Virtually restore the unmodified microphone level. | |
85 *sample = ClipSampleFloat( | |
86 *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.
| |
87 *undo_mic_level_)); | |
88 } else { | |
89 // Simulate the mic gain only. | |
90 *sample = ClipSampleFloat( | |
91 *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.
| |
92 } | |
93 } | |
94 }; | |
95 | |
96 } // namespace | |
97 | |
98 FakeRecordingDevice::FakeRecordingDevice(int initial_mic_level, DeviceKind kind) | |
99 : mic_level_(initial_mic_level) { | |
100 switch (kind) { | |
101 case FakeRecordingDevice::DeviceKind::IDENTITY: | |
102 worker_ = rtc::MakeUnique<FakeRecordingDeviceIdentity>( | |
103 mic_level_, undo_mic_level_); | |
104 break; | |
105 case FakeRecordingDevice::DeviceKind::LINEAR: | |
106 worker_ = rtc::MakeUnique<FakeRecordingDeviceLinear>( | |
107 mic_level_, undo_mic_level_); | |
108 break; | |
109 default: | |
110 RTC_NOTREACHED(); | |
111 break; | |
112 } | |
113 } | |
114 | |
115 FakeRecordingDevice::~FakeRecordingDevice() = default; | |
116 | |
117 void FakeRecordingDevice::SimulateAnalogGain(ChannelBuffer<float>* buffer) { | |
118 RTC_DCHECK(worker_); | |
119 size_t number_of_samples = buffer->num_frames(); | |
120 for (size_t i = 0; i < buffer->num_channels(); ++i) { | |
121 std::for_each(buffer->channels()[i], | |
122 buffer->channels()[i] + number_of_samples, | |
123 [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
| |
124 } | |
125 } | |
126 | |
127 void FakeRecordingDevice::SimulateAnalogGain(AudioFrame* buffer) { | |
128 RTC_DCHECK(worker_); | |
129 const size_t number_of_samples = | |
130 buffer->samples_per_channel_ * buffer->num_channels_; | |
131 RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples); | |
132 std::for_each(buffer->mutable_data(), | |
133 buffer->mutable_data() + number_of_samples, | |
134 [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
| |
135 } | |
136 | |
137 } // namespace test | |
138 } // namespace webrtc | |
OLD | NEW |