blob: 3ac5e712911f2089fa6ae626e401852742d10980 [file] [log] [blame]
andrew@webrtc.org60730cf2014-01-07 17:45:09 +00001/*
2 * Copyright (c) 2014 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_processing/audio_processing_impl.h"
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_processing/test/test_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "test/gmock.h"
15#include "test/gtest.h"
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000016
17using ::testing::Invoke;
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000018
19namespace webrtc {
peaha9cc40b2017-06-29 08:32:09 -070020namespace {
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000021
22class MockInitialize : public AudioProcessingImpl {
23 public:
peah88ac8532016-09-12 16:47:25 -070024 explicit MockInitialize(const webrtc::Config& config)
25 : AudioProcessingImpl(config) {}
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000026
andrew@webrtc.orge84978f2014-01-25 02:09:06 +000027 MOCK_METHOD0(InitializeLocked, int());
danilchap56359be2017-09-07 07:53:45 -070028 int RealInitializeLocked() RTC_NO_THREAD_SAFETY_ANALYSIS {
pbos@webrtc.org788acd12014-12-15 09:41:24 +000029 return AudioProcessingImpl::InitializeLocked();
30 }
peaha9cc40b2017-06-29 08:32:09 -070031
Niels Möller6f72f562017-10-19 13:15:17 +020032 MOCK_CONST_METHOD0(AddRef, void());
33 MOCK_CONST_METHOD0(Release, rtc::RefCountReleaseStatus());
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000034};
35
Alex Loikob5c9a792018-04-16 16:31:22 +020036void GenerateFixedFrame(int16_t audio_level,
37 size_t input_rate,
38 size_t num_channels,
39 AudioFrame* fixed_frame) {
40 const size_t samples_per_input_channel = rtc::CheckedDivExact(
41 input_rate, static_cast<size_t>(rtc::CheckedDivExact(
42 1000, AudioProcessing::kChunkSizeMs)));
43 fixed_frame->samples_per_channel_ = samples_per_input_channel;
44 fixed_frame->sample_rate_hz_ = input_rate;
45 fixed_frame->num_channels_ = num_channels;
46
47 RTC_DCHECK_LE(samples_per_input_channel * num_channels,
48 AudioFrame::kMaxDataSizeSamples);
49 for (size_t i = 0; i < samples_per_input_channel * num_channels; ++i) {
50 fixed_frame->mutable_data()[i] = audio_level;
51 }
52}
53
peaha9cc40b2017-06-29 08:32:09 -070054} // namespace
55
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000056TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
peah88ac8532016-09-12 16:47:25 -070057 webrtc::Config config;
andrew@webrtc.orge84978f2014-01-25 02:09:06 +000058 MockInitialize mock(config);
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000059 ON_CALL(mock, InitializeLocked())
60 .WillByDefault(Invoke(&mock, &MockInitialize::RealInitializeLocked));
61
62 EXPECT_CALL(mock, InitializeLocked()).Times(1);
63 mock.Initialize();
64
65 AudioFrame frame;
peah2ace3f92016-09-10 04:42:27 -070066 // Call with the default parameters; there should be an init.
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000067 frame.num_channels_ = 1;
68 SetFrameSampleRate(&frame, 16000);
Per Åhgren4bdced52017-06-27 16:00:38 +020069 EXPECT_CALL(mock, InitializeLocked()).Times(0);
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000070 EXPECT_NOERR(mock.ProcessStream(&frame));
aluebsb0319552016-03-17 20:39:53 -070071 EXPECT_NOERR(mock.ProcessReverseStream(&frame));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000072
73 // New sample rate. (Only impacts ProcessStream).
74 SetFrameSampleRate(&frame, 32000);
Yves Gerey665174f2018-06-19 15:03:05 +020075 EXPECT_CALL(mock, InitializeLocked()).Times(1);
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000076 EXPECT_NOERR(mock.ProcessStream(&frame));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000077
78 // New number of channels.
peah2ace3f92016-09-10 04:42:27 -070079 // TODO(peah): Investigate why this causes 2 inits.
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000080 frame.num_channels_ = 2;
Yves Gerey665174f2018-06-19 15:03:05 +020081 EXPECT_CALL(mock, InitializeLocked()).Times(2);
andrew@webrtc.orga8b97372014-03-10 22:26:12 +000082 EXPECT_NOERR(mock.ProcessStream(&frame));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000083 // ProcessStream sets num_channels_ == num_output_channels.
84 frame.num_channels_ = 2;
aluebsb0319552016-03-17 20:39:53 -070085 EXPECT_NOERR(mock.ProcessReverseStream(&frame));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000086
aluebsb0319552016-03-17 20:39:53 -070087 // A new sample rate passed to ProcessReverseStream should cause an init.
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000088 SetFrameSampleRate(&frame, 16000);
Alex Luebs5b830fe2016-03-08 17:52:52 +010089 EXPECT_CALL(mock, InitializeLocked()).Times(1);
aluebsb0319552016-03-17 20:39:53 -070090 EXPECT_NOERR(mock.ProcessReverseStream(&frame));
andrew@webrtc.org60730cf2014-01-07 17:45:09 +000091}
92
Alessio Bazzicac054e782018-04-16 12:10:09 +020093TEST(AudioProcessingImplTest, UpdateCapturePreGainRuntimeSetting) {
Alex Loikob5c9a792018-04-16 16:31:22 +020094 std::unique_ptr<AudioProcessing> apm(AudioProcessingBuilder().Create());
95 webrtc::AudioProcessing::Config apm_config;
96 apm_config.pre_amplifier.enabled = true;
97 apm_config.pre_amplifier.fixed_gain_factor = 1.f;
98 apm->ApplyConfig(apm_config);
99
100 AudioFrame frame;
101 constexpr int16_t audio_level = 10000;
102 constexpr size_t input_rate = 48000;
103 constexpr size_t num_channels = 2;
104
105 GenerateFixedFrame(audio_level, input_rate, num_channels, &frame);
106 apm->ProcessStream(&frame);
107 EXPECT_EQ(frame.data()[100], audio_level)
108 << "With factor 1, frame shouldn't be modified.";
109
110 constexpr float gain_factor = 2.f;
111 apm->SetRuntimeSetting(
112 AudioProcessing::RuntimeSetting::CreateCapturePreGain(gain_factor));
113
114 // Process for two frames to have time to ramp up gain.
115 for (int i = 0; i < 2; ++i) {
116 GenerateFixedFrame(audio_level, input_rate, num_channels, &frame);
117 apm->ProcessStream(&frame);
118 }
119 EXPECT_EQ(frame.data()[100], gain_factor * audio_level)
120 << "Frame should be amplified.";
Alessio Bazzicac054e782018-04-16 12:10:09 +0200121}
122
andrew@webrtc.org60730cf2014-01-07 17:45:09 +0000123} // namespace webrtc