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..2b5b13b71f32cfcff34cf5d753d989522f785b0b |
--- /dev/null |
+++ b/webrtc/modules/audio_processing/test/fake_recording_device.cc |
@@ -0,0 +1,128 @@ |
+/* |
+ * 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 "webrtc/base/logging.h" |
+ |
+namespace webrtc { |
+ |
+FakeRecordingDevice::FakeRecordingDevice(MicrophoneKind mapping_kind) |
+ : mapping_kind_(mapping_kind) { |
+ // Create the analog gain simulatory callback depending on the wanted |
+ // microphone kind. |
+ switch (mapping_kind_) { |
+ case MicrophoneKind::kIdentity: { |
+ simulator_callback_int16_ = AnalogGainSimulatorIdentityInt16(); |
peah-webrtc
2017/05/16 12:19:36
These are not used as callbacks, so I don't think
AleBzk
2017/05/17 11:52:23
Acknowledged.
|
+ simulator_callback_float_ = AnalogGainSimulatorIdentityFloat(); |
+ break; |
+ } |
+ case MicrophoneKind::kLinear: { |
+ simulator_callback_int16_ = AnalogGainSimulatorLinearInt16(); |
peah-webrtc
2017/05/16 12:19:36
I would rather have an interface with different im
AleBzk
2017/05/17 11:52:23
Perfect. Let's then go for interface + implementat
|
+ simulator_callback_float_ = AnalogGainSimulatorLinearFloat(); |
+ break; |
+ } |
+ default: { RTC_NOTREACHED(); } |
+ } |
+} |
+ |
+FakeRecordingDevice::~FakeRecordingDevice() = default; |
+ |
+void FakeRecordingDevice::SimulateAnalogGain( |
+ int level, rtc::Optional<int> real_device_level, |
+ std::vector<rtc::ArrayView<float>> buffer) { |
+ for (size_t i = 0; i < buffer.size(); ++i) { |
+ std::transform( |
peah-webrtc
2017/05/16 12:19:35
I think std::for_each is better suited here.
AleBzk
2017/05/17 11:52:23
Acknowledged.
|
+ buffer[i].begin(), buffer[i].end(), buffer[i].begin(), |
+ [this, level, real_device_level](float x) { |
+ return simulator_callback_float_(x, level, real_device_level); |
peah-webrtc
2017/05/16 12:19:36
As you stated offline, this will not scale with me
AleBzk
2017/05/17 11:52:23
Acknowledged.
|
+ }); |
+ } |
+} |
+ |
+void FakeRecordingDevice::SimulateAnalogGain( |
peah-webrtc
2017/05/16 12:19:36
Why is this needed as a separate method?
AleBzk
2017/05/17 11:52:23
Please, see my answer to a related question of you
|
+ int level, rtc::Optional<int> real_device_level, |
+ ChannelBuffer<float>* buffer) { |
+ std::vector<rtc::ArrayView<float>> buffer_view; |
+ for (size_t i = 0; i < buffer->num_channels(); ++i) { |
+ buffer_view.emplace_back(buffer->channels()[i], buffer->num_frames()); |
+ } |
+ SimulateAnalogGain(level, real_device_level, buffer_view); |
+} |
+ |
+void FakeRecordingDevice::SimulateAnalogGain( |
+ int level, rtc::Optional<int> real_device_level, AudioFrame* buffer) { |
+ const size_t number_of_samples = |
+ buffer->samples_per_channel_ * buffer->num_channels_; |
+ RTC_DCHECK_LE(number_of_samples, AudioFrame::kMaxDataSizeSamples); |
+ std::transform( |
peah-webrtc
2017/05/16 12:19:36
std::for_each
AleBzk
2017/05/17 11:52:23
Acknowledged.
|
+ buffer->data_, buffer->data_ + number_of_samples, buffer->data_, |
+ [this, level, real_device_level](int16_t x) { |
+ return simulator_callback_int16_(x, level, real_device_level); |
+ }); |
+} |
+ |
+SimulatorCallbackInt16 FakeRecordingDevice::AnalogGainSimulatorIdentityInt16() { |
+ return [this](int16_t sample, int level, |
+ rtc::Optional<int> real_device_level) { |
+ return sample; |
+ }; |
+} |
+ |
+SimulatorCallbackFloat FakeRecordingDevice::AnalogGainSimulatorIdentityFloat() { |
+ return [this](float sample, int level, rtc::Optional<int> real_device_level) { |
+ return sample; |
+ }; |
+} |
+ |
+SimulatorCallbackInt16 FakeRecordingDevice::AnalogGainSimulatorLinearInt16() { |
+ return [this](int16_t sample, int level, |
+ rtc::Optional<int> real_device_level) { |
+ float sample_f = static_cast<float>(sample); |
+ |
+ // Virtually restore the unmodified microphone level. |
+ if (real_device_level) { |
+ RTC_DCHECK_GT(*real_device_level, 0) |
+ << "zero real device level, cannot undo mic level"; |
+ sample_f = ClipSample( |
+ sample_f * 255.0f / static_cast<float>(*real_device_level)); |
+ } |
+ |
+ // Simulate the mic gain. |
+ return ClipSample(sample_f * static_cast<float>(level) / 255.0f); |
+ }; |
+} |
+ |
+SimulatorCallbackFloat FakeRecordingDevice::AnalogGainSimulatorLinearFloat() { |
+ return [this](float sample, int level, rtc::Optional<int> real_device_level) { |
+ // Virtually restore the unmodified microphone level. |
+ if (real_device_level) { |
+ RTC_DCHECK_GT(*real_device_level, 0) |
+ << "zero real device level, cannot undo mic level"; |
+ sample = ClipSample( |
+ sample * 255.0f / static_cast<float>(*real_device_level)); |
+ } |
+ |
+ // Simulate the mic gain. |
+ return ClipSample(sample * static_cast<float>(level) / 255.0f); |
+ }; |
+} |
+ |
+int16_t FakeRecordingDevice::ClipSample(int16_t sample) { |
+ return sample < kSampleMinInt16 ? |
+ kSampleMinInt16 : (sample > kSampleMaxInt16 ? kSampleMaxInt16 : sample); |
peah-webrtc
2017/05/16 12:19:35
Use std::min/std::max instead
peah-webrtc
2017/05/16 12:19:36
Why do you clip the sample value to +-255?
AleBzk
2017/05/17 11:52:23
Done.
AleBzk
2017/05/17 11:52:23
Right, I got confused with the mic level.
|
+} |
+ |
+float FakeRecordingDevice::ClipSample(float sample) { |
+ return sample < kSampleMinFloat ? |
peah-webrtc
2017/05/16 12:19:36
Use std::min/std::max instead
AleBzk
2017/05/17 11:52:23
Done.
|
+ kSampleMinFloat : (sample > kSampleMaxFloat ? kSampleMaxFloat : sample); |
+} |
+ |
+} // namespace webrtc |