blob: 05c5003459e94292af27d8eee45e289efb322e65 [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"
kwibergac9f8762016-09-30 22:29:43 -070015#include "webrtc/test/gtest.h"
solenberg566ef242015-11-06 15:34:49 -080016#include "webrtc/test/mock_voice_engine.h"
17
18namespace webrtc {
19namespace test {
20namespace {
21
aleloi04c07222016-11-22 06:42:53 -080022const int kSampleRate = 8000;
23const int kNumberOfChannels = 1;
24const int kBytesPerSample = 2;
aleloidd310712016-11-17 06:28:59 -080025
aleloi04c07222016-11-22 06:42:53 -080026struct ConfigHelper {
27 ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
28 EXPECT_CALL(mock_voice_engine, RegisterVoiceEngineObserver(testing::_))
29 .WillOnce(testing::Return(0));
30 EXPECT_CALL(mock_voice_engine, DeRegisterVoiceEngineObserver())
31 .WillOnce(testing::Return(0));
32 EXPECT_CALL(mock_voice_engine, audio_device_module())
33 .Times(testing::AtLeast(1));
34 EXPECT_CALL(mock_voice_engine, audio_processing())
35 .Times(testing::AtLeast(1));
36 EXPECT_CALL(mock_voice_engine, audio_transport())
37 .WillRepeatedly(testing::Return(&audio_transport));
38
39 auto device = static_cast<MockAudioDeviceModule*>(
40 voice_engine().audio_device_module());
41
42 // Populate the audio transport proxy pointer to the most recent
43 // transport connected to the Audio Device.
44 ON_CALL(*device, RegisterAudioCallback(testing::_))
45 .WillByDefault(testing::Invoke([this](AudioTransport* transport) {
46 registered_audio_transport = transport;
47 return 0;
48 }));
49
50 audio_state_config.voice_engine = &mock_voice_engine;
51 audio_state_config.audio_mixer = audio_mixer;
solenberg566ef242015-11-06 15:34:49 -080052 }
aleloi04c07222016-11-22 06:42:53 -080053 AudioState::Config& config() { return audio_state_config; }
54 MockVoiceEngine& voice_engine() { return mock_voice_engine; }
55 rtc::scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
56 MockAudioTransport& original_audio_transport() { return audio_transport; }
57 AudioTransport* audio_transport_proxy() { return registered_audio_transport; }
solenberg566ef242015-11-06 15:34:49 -080058
59 private:
aleloi04c07222016-11-22 06:42:53 -080060 testing::StrictMock<MockVoiceEngine> mock_voice_engine;
61 AudioState::Config audio_state_config;
62 rtc::scoped_refptr<AudioMixer> audio_mixer;
63 MockAudioTransport audio_transport;
64 AudioTransport* registered_audio_transport = nullptr;
solenberg566ef242015-11-06 15:34:49 -080065};
aleloi04c07222016-11-22 06:42:53 -080066
67class FakeAudioSource : public AudioMixer::Source {
68 public:
69 // TODO(aleloi): Valid overrides commented out, because the gmock
70 // methods don't use any override declarations, and we want to avoid
71 // warnings from -Winconsistent-missing-override. See
72 // http://crbug.com/428099.
73 int Ssrc() const /*override*/ { return 0; }
74
75 int PreferredSampleRate() const /*override*/ { return kSampleRate; }
76
77 MOCK_METHOD2(GetAudioFrameWithInfo,
78 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame));
79};
80
solenberg566ef242015-11-06 15:34:49 -080081} // namespace
82
83TEST(AudioStateTest, Create) {
84 ConfigHelper helper;
85 rtc::scoped_refptr<AudioState> audio_state =
86 AudioState::Create(helper.config());
87 EXPECT_TRUE(audio_state.get());
88}
89
90TEST(AudioStateTest, ConstructDestruct) {
91 ConfigHelper helper;
kwibergfffa42b2016-02-23 10:46:32 -080092 std::unique_ptr<internal::AudioState> audio_state(
solenberg566ef242015-11-06 15:34:49 -080093 new internal::AudioState(helper.config()));
94}
95
96TEST(AudioStateTest, GetVoiceEngine) {
97 ConfigHelper helper;
kwibergfffa42b2016-02-23 10:46:32 -080098 std::unique_ptr<internal::AudioState> audio_state(
solenberg566ef242015-11-06 15:34:49 -080099 new internal::AudioState(helper.config()));
100 EXPECT_EQ(audio_state->voice_engine(), &helper.voice_engine());
101}
102
103TEST(AudioStateTest, TypingNoiseDetected) {
104 ConfigHelper helper;
kwibergfffa42b2016-02-23 10:46:32 -0800105 std::unique_ptr<internal::AudioState> audio_state(
solenberg566ef242015-11-06 15:34:49 -0800106 new internal::AudioState(helper.config()));
107 VoiceEngineObserver* voe_observer =
108 static_cast<VoiceEngineObserver*>(audio_state.get());
109 EXPECT_FALSE(audio_state->typing_noise_detected());
110
111 voe_observer->CallbackOnError(-1, VE_NOT_INITED);
112 EXPECT_FALSE(audio_state->typing_noise_detected());
113
114 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_WARNING);
115 EXPECT_TRUE(audio_state->typing_noise_detected());
116 voe_observer->CallbackOnError(-1, VE_NOT_INITED);
117 EXPECT_TRUE(audio_state->typing_noise_detected());
118
119 voe_observer->CallbackOnError(-1, VE_TYPING_NOISE_OFF_WARNING);
120 EXPECT_FALSE(audio_state->typing_noise_detected());
121 voe_observer->CallbackOnError(-1, VE_NOT_INITED);
122 EXPECT_FALSE(audio_state->typing_noise_detected());
123}
aleloidd310712016-11-17 06:28:59 -0800124
125// Test that RecordedDataIsAvailable calls get to the original transport.
aleloi04c07222016-11-22 06:42:53 -0800126TEST(AudioStateAudioPathTest, RecordedAudioArrivesAtOriginalTransport) {
aleloidd310712016-11-17 06:28:59 -0800127 ConfigHelper helper;
aleloidd310712016-11-17 06:28:59 -0800128
aleloi04c07222016-11-22 06:42:53 -0800129 rtc::scoped_refptr<AudioState> audio_state =
130 AudioState::Create(helper.config());
131
132 // Setup completed. Ensure call of original transport is forwarded to new.
133 uint32_t new_mic_level;
134 EXPECT_CALL(
135 helper.original_audio_transport(),
136 RecordedDataIsAvailable(nullptr, kSampleRate / 100, kBytesPerSample,
137 kNumberOfChannels, kSampleRate, 0, 0, 0, false,
138 testing::Ref(new_mic_level)));
139
140 helper.audio_transport_proxy()->RecordedDataIsAvailable(
141 nullptr, kSampleRate / 100, kBytesPerSample, kNumberOfChannels,
142 kSampleRate, 0, 0, 0, false, new_mic_level);
143}
144
145TEST(AudioStateAudioPathTest,
146 QueryingProxyForAudioShouldResultInGetAudioCallOnMixerSource) {
147 ConfigHelper helper;
148
149 rtc::scoped_refptr<AudioState> audio_state =
150 AudioState::Create(helper.config());
151
152 FakeAudioSource fake_source;
153
154 helper.mixer()->AddSource(&fake_source);
155
156 EXPECT_CALL(fake_source, GetAudioFrameWithInfo(testing::_, testing::_))
157 .WillOnce(
158 testing::Invoke([](int sample_rate_hz, AudioFrame* audio_frame) {
159 audio_frame->sample_rate_hz_ = sample_rate_hz;
160 audio_frame->samples_per_channel_ = sample_rate_hz / 100;
161 audio_frame->num_channels_ = kNumberOfChannels;
162 return AudioMixer::Source::AudioFrameInfo::kNormal;
aleloidd310712016-11-17 06:28:59 -0800163 }));
164
aleloi04c07222016-11-22 06:42:53 -0800165 int16_t audio_buffer[kSampleRate / 100 * kNumberOfChannels];
166 size_t n_samples_out;
167 int64_t elapsed_time_ms;
168 int64_t ntp_time_ms;
169 helper.audio_transport_proxy()->NeedMorePlayData(
170 kSampleRate / 100, kBytesPerSample, kNumberOfChannels, kSampleRate,
171 audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
aleloidd310712016-11-17 06:28:59 -0800172}
solenberg566ef242015-11-06 15:34:49 -0800173} // namespace test
174} // namespace webrtc