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