1 /*
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
11 #include <memory>
12
13 #include "audio/audio_state.h"
14 #include "modules/audio_mixer/audio_mixer_impl.h"
15 #include "modules/audio_processing/include/mock_audio_processing.h"
16 #include "test/gtest.h"
17 #include "test/mock_voice_engine.h"
18
19 namespace webrtc {
20 namespace test {
21 namespace {
22
23 const int kSampleRate = 8000;
24 const int kNumberOfChannels = 1;
25 const int kBytesPerSample = 2;
26
27 struct ConfigHelper {
ConfigHelperwebrtc::test::__anon6bfcb64d0111::ConfigHelper28 ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
29 EXPECT_CALL(mock_voice_engine, audio_transport())
30 .WillRepeatedly(testing::Return(&audio_transport));
31
32 audio_state_config.voice_engine = &mock_voice_engine;
33 audio_state_config.audio_mixer = audio_mixer;
34 audio_state_config.audio_processing =
35 new rtc::RefCountedObject<MockAudioProcessing>();
36 }
configwebrtc::test::__anon6bfcb64d0111::ConfigHelper37 AudioState::Config& config() { return audio_state_config; }
voice_enginewebrtc::test::__anon6bfcb64d0111::ConfigHelper38 MockVoiceEngine& voice_engine() { return mock_voice_engine; }
mixerwebrtc::test::__anon6bfcb64d0111::ConfigHelper39 rtc::scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
original_audio_transportwebrtc::test::__anon6bfcb64d0111::ConfigHelper40 MockAudioTransport& original_audio_transport() { return audio_transport; }
41
42 private:
43 testing::StrictMock<MockVoiceEngine> mock_voice_engine;
44 AudioState::Config audio_state_config;
45 rtc::scoped_refptr<AudioMixer> audio_mixer;
46 MockAudioTransport audio_transport;
47 };
48
49 class FakeAudioSource : public AudioMixer::Source {
50 public:
51 // TODO(aleloi): Valid overrides commented out, because the gmock
52 // methods don't use any override declarations, and we want to avoid
53 // warnings from -Winconsistent-missing-override. See
54 // http://crbug.com/428099.
Ssrc() const55 int Ssrc() const /*override*/ { return 0; }
56
PreferredSampleRate() const57 int PreferredSampleRate() const /*override*/ { return kSampleRate; }
58
59 MOCK_METHOD2(GetAudioFrameWithInfo,
60 AudioFrameInfo(int sample_rate_hz, AudioFrame* audio_frame));
61 };
62
63 } // namespace
64
TEST(AudioStateTest,Create)65 TEST(AudioStateTest, Create) {
66 ConfigHelper helper;
67 rtc::scoped_refptr<AudioState> audio_state =
68 AudioState::Create(helper.config());
69 EXPECT_TRUE(audio_state.get());
70 }
71
TEST(AudioStateTest,ConstructDestruct)72 TEST(AudioStateTest, ConstructDestruct) {
73 ConfigHelper helper;
74 std::unique_ptr<internal::AudioState> audio_state(
75 new internal::AudioState(helper.config()));
76 }
77
TEST(AudioStateTest,GetVoiceEngine)78 TEST(AudioStateTest, GetVoiceEngine) {
79 ConfigHelper helper;
80 std::unique_ptr<internal::AudioState> audio_state(
81 new internal::AudioState(helper.config()));
82 EXPECT_EQ(audio_state->voice_engine(), &helper.voice_engine());
83 }
84
85 // Test that RecordedDataIsAvailable calls get to the original transport.
TEST(AudioStateAudioPathTest,RecordedAudioArrivesAtOriginalTransport)86 TEST(AudioStateAudioPathTest, RecordedAudioArrivesAtOriginalTransport) {
87 ConfigHelper helper;
88
89 rtc::scoped_refptr<AudioState> audio_state =
90 AudioState::Create(helper.config());
91
92 // Setup completed. Ensure call of original transport is forwarded to new.
93 uint32_t new_mic_level;
94 EXPECT_CALL(
95 helper.original_audio_transport(),
96 RecordedDataIsAvailable(nullptr, kSampleRate / 100, kBytesPerSample,
97 kNumberOfChannels, kSampleRate, 0, 0, 0, false,
98 testing::Ref(new_mic_level)));
99
100 audio_state->audio_transport()->RecordedDataIsAvailable(
101 nullptr, kSampleRate / 100, kBytesPerSample, kNumberOfChannels,
102 kSampleRate, 0, 0, 0, false, new_mic_level);
103 }
104
TEST(AudioStateAudioPathTest,QueryingProxyForAudioShouldResultInGetAudioCallOnMixerSource)105 TEST(AudioStateAudioPathTest,
106 QueryingProxyForAudioShouldResultInGetAudioCallOnMixerSource) {
107 ConfigHelper helper;
108
109 rtc::scoped_refptr<AudioState> audio_state =
110 AudioState::Create(helper.config());
111
112 FakeAudioSource fake_source;
113
114 helper.mixer()->AddSource(&fake_source);
115
116 EXPECT_CALL(fake_source, GetAudioFrameWithInfo(testing::_, testing::_))
117 .WillOnce(
118 testing::Invoke([](int sample_rate_hz, AudioFrame* audio_frame) {
119 audio_frame->sample_rate_hz_ = sample_rate_hz;
120 audio_frame->samples_per_channel_ = sample_rate_hz / 100;
121 audio_frame->num_channels_ = kNumberOfChannels;
122 return AudioMixer::Source::AudioFrameInfo::kNormal;
123 }));
124
125 int16_t audio_buffer[kSampleRate / 100 * kNumberOfChannels];
126 size_t n_samples_out;
127 int64_t elapsed_time_ms;
128 int64_t ntp_time_ms;
129 audio_state->audio_transport()->NeedMorePlayData(
130 kSampleRate / 100, kBytesPerSample, kNumberOfChannels, kSampleRate,
131 audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
132 }
133 } // namespace test
134 } // namespace webrtc
135