blob: ffaacb62ca3cfe56e90340fb403b8766ada9cf47 [file] [log] [blame]
solenberg566ef242015-11-06 15:34:49 -08001/*
2 * Copyright (c) 2015 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
kwibergfffa42b2016-02-23 10:46:32 -080011#include <memory>
12
solenberg566ef242015-11-06 15:34:49 -080013#include "webrtc/audio/audio_state.h"
aleloi10111bc2016-11-17 06:48:48 -080014#include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
peaha9cc40b2017-06-29 08:32:09 -070015#include "webrtc/modules/audio_processing/include/mock_audio_processing.h"
kwibergac9f8762016-09-30 22:29:43 -070016#include "webrtc/test/gtest.h"
solenberg566ef242015-11-06 15:34:49 -080017#include "webrtc/test/mock_voice_engine.h"
18
19namespace webrtc {
20namespace test {
21namespace {
22
aleloi04c07222016-11-22 06:42:53 -080023const int kSampleRate = 8000;
24const int kNumberOfChannels = 1;
25const int kBytesPerSample = 2;
aleloidd310712016-11-17 06:28:59 -080026
aleloi04c07222016-11-22 06:42:53 -080027struct ConfigHelper {
28 ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
29 EXPECT_CALL(mock_voice_engine, RegisterVoiceEngineObserver(testing::_))
30 .WillOnce(testing::Return(0));
31 EXPECT_CALL(mock_voice_engine, DeRegisterVoiceEngineObserver())
32 .WillOnce(testing::Return(0));
33 EXPECT_CALL(mock_voice_engine, audio_device_module())
34 .Times(testing::AtLeast(1));
aleloi04c07222016-11-22 06:42:53 -080035 EXPECT_CALL(mock_voice_engine, audio_transport())
36 .WillRepeatedly(testing::Return(&audio_transport));
37
38 auto device = static_cast<MockAudioDeviceModule*>(
39 voice_engine().audio_device_module());
40
41 // Populate the audio transport proxy pointer to the most recent
42 // transport connected to the Audio Device.
43 ON_CALL(*device, RegisterAudioCallback(testing::_))
44 .WillByDefault(testing::Invoke([this](AudioTransport* transport) {
45 registered_audio_transport = transport;
46 return 0;
47 }));
48
49 audio_state_config.voice_engine = &mock_voice_engine;
50 audio_state_config.audio_mixer = audio_mixer;
peaha9cc40b2017-06-29 08:32:09 -070051 audio_state_config.audio_processing =
52 new rtc::RefCountedObject<MockAudioProcessing>();
solenberg566ef242015-11-06 15:34:49 -080053 }
aleloi04c07222016-11-22 06:42:53 -080054 AudioState::Config& config() { return audio_state_config; }
55 MockVoiceEngine& voice_engine() { return mock_voice_engine; }
56 rtc::scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
57 MockAudioTransport& original_audio_transport() { return audio_transport; }
58 AudioTransport* audio_transport_proxy() { return registered_audio_transport; }
solenberg566ef242015-11-06 15:34:49 -080059
60 private:
aleloi04c07222016-11-22 06:42:53 -080061 testing::StrictMock<MockVoiceEngine> mock_voice_engine;
62 AudioState::Config audio_state_config;
63 rtc::scoped_refptr<AudioMixer> audio_mixer;
64 MockAudioTransport audio_transport;
65 AudioTransport* registered_audio_transport = nullptr;
solenberg566ef242015-11-06 15:34:49 -080066};
aleloi04c07222016-11-22 06:42:53 -080067
68class FakeAudioSource : public AudioMixer::Source {
69 public:
70 // TODO(aleloi): Valid overrides commented out, because the gmock
71 // methods don't use any override declarations, and we want to avoid
72 // warnings from -Winconsistent-missing-override. See
73 // http://crbug.com/428099.
74 int Ssrc() const /*override*/ { return 0; }
75
76 int PreferredSampleRate() const /*override*/ { return kSampleRate; }
77
78 MOCK_METHOD2(GetAudioFrameWithInfo,
79 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame));
80};
81
solenberg566ef242015-11-06 15:34:49 -080082} // namespace
83
84TEST(AudioStateTest, Create) {
85 ConfigHelper helper;
86 rtc::scoped_refptr<AudioState> audio_state =
87 AudioState::Create(helper.config());
88 EXPECT_TRUE(audio_state.get());
89}
90
91TEST(AudioStateTest, ConstructDestruct) {
92 ConfigHelper helper;
kwibergfffa42b2016-02-23 10:46:32 -080093 std::unique_ptr<internal::AudioState> audio_state(
solenberg566ef242015-11-06 15:34:49 -080094 new internal::AudioState(helper.config()));
95}
96
97TEST(AudioStateTest, GetVoiceEngine) {
98 ConfigHelper helper;
kwibergfffa42b2016-02-23 10:46:32 -080099 std::unique_ptr<internal::AudioState> audio_state(
solenberg566ef242015-11-06 15:34:49 -0800100 new internal::AudioState(helper.config()));
101 EXPECT_EQ(audio_state->voice_engine(), &helper.voice_engine());
102}
103
104TEST(AudioStateTest, TypingNoiseDetected) {
105 ConfigHelper helper;
kwibergfffa42b2016-02-23 10:46:32 -0800106 std::unique_ptr<internal::AudioState> audio_state(
solenberg566ef242015-11-06 15:34:49 -0800107 new internal::AudioState(helper.config()));
108 VoiceEngineObserver* voe_observer =
109 static_cast<VoiceEngineObserver*>(audio_state.get());
110 EXPECT_FALSE(audio_state->typing_noise_detected());
111
112 voe_observer->CallbackOnError(-1, VE_NOT_INITED);
113 EXPECT_FALSE(audio_state->typing_noise_detected());
114
115 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_WARNING);
116 EXPECT_TRUE(audio_state->typing_noise_detected());
117 voe_observer->CallbackOnError(-1, VE_NOT_INITED);
118 EXPECT_TRUE(audio_state->typing_noise_detected());
119
120 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_OFF_WARNING);
121 EXPECT_FALSE(audio_state->typing_noise_detected());
122 voe_observer->CallbackOnError(-1, VE_NOT_INITED);
123 EXPECT_FALSE(audio_state->typing_noise_detected());
124}
aleloidd310712016-11-17 06:28:59 -0800125
126// Test that RecordedDataIsAvailable calls get to the original transport.
aleloi04c07222016-11-22 06:42:53 -0800127TEST(AudioStateAudioPathTest, RecordedAudioArrivesAtOriginalTransport) {
aleloidd310712016-11-17 06:28:59 -0800128 ConfigHelper helper;
aleloidd310712016-11-17 06:28:59 -0800129
aleloi04c07222016-11-22 06:42:53 -0800130 rtc::scoped_refptr<AudioState> audio_state =
131 AudioState::Create(helper.config());
132
133 // Setup completed. Ensure call of original transport is forwarded to new.
134 uint32_t new_mic_level;
135 EXPECT_CALL(
136 helper.original_audio_transport(),
137 RecordedDataIsAvailable(nullptr, kSampleRate / 100, kBytesPerSample,
138 kNumberOfChannels, kSampleRate, 0, 0, 0, false,
139 testing::Ref(new_mic_level)));
140
141 helper.audio_transport_proxy()->RecordedDataIsAvailable(
142 nullptr, kSampleRate / 100, kBytesPerSample, kNumberOfChannels,
143 kSampleRate, 0, 0, 0, false, new_mic_level);
144}
145
146TEST(AudioStateAudioPathTest,
147 QueryingProxyForAudioShouldResultInGetAudioCallOnMixerSource) {
148 ConfigHelper helper;
149
150 rtc::scoped_refptr<AudioState> audio_state =
151 AudioState::Create(helper.config());
152
153 FakeAudioSource fake_source;
154
155 helper.mixer()->AddSource(&fake_source);
156
157 EXPECT_CALL(fake_source, GetAudioFrameWithInfo(testing::_, testing::_))
158 .WillOnce(
159 testing::Invoke([](int sample_rate_hz, AudioFrame* audio_frame) {
160 audio_frame->sample_rate_hz_ = sample_rate_hz;
161 audio_frame->samples_per_channel_ = sample_rate_hz / 100;
162 audio_frame->num_channels_ = kNumberOfChannels;
163 return AudioMixer::Source::AudioFrameInfo::kNormal;
aleloidd310712016-11-17 06:28:59 -0800164 }));
165
aleloi04c07222016-11-22 06:42:53 -0800166 int16_t audio_buffer[kSampleRate / 100 * kNumberOfChannels];
167 size_t n_samples_out;
168 int64_t elapsed_time_ms;
169 int64_t ntp_time_ms;
170 helper.audio_transport_proxy()->NeedMorePlayData(
171 kSampleRate / 100, kBytesPerSample, kNumberOfChannels, kSampleRate,
172 audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
aleloidd310712016-11-17 06:28:59 -0800173}
solenberg566ef242015-11-06 15:34:49 -0800174} // namespace test
175} // namespace webrtc