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 "audio/audio_state.h"
12 
13 #include <memory>
14 #include <vector>
15 
16 #include "call/test/mock_audio_send_stream.h"
17 #include "modules/audio_device/include/mock_audio_device.h"
18 #include "modules/audio_mixer/audio_mixer_impl.h"
19 #include "modules/audio_processing/include/mock_audio_processing.h"
20 #include "rtc_base/ref_counted_object.h"
21 #include "test/gtest.h"
22 
23 namespace webrtc {
24 namespace test {
25 namespace {
26 
27 using ::testing::_;
28 using ::testing::Matcher;
29 
30 constexpr int kSampleRate = 16000;
31 constexpr int kNumberOfChannels = 1;
32 
33 struct ConfigHelper {
ConfigHelperwebrtc::test::__anon970564350111::ConfigHelper34   ConfigHelper() : audio_mixer(AudioMixerImpl::Create()) {
35     audio_state_config.audio_mixer = audio_mixer;
36     audio_state_config.audio_processing =
37         new rtc::RefCountedObject<testing::NiceMock<MockAudioProcessing>>();
38     audio_state_config.audio_device_module =
39         new rtc::RefCountedObject<MockAudioDeviceModule>();
40   }
configwebrtc::test::__anon970564350111::ConfigHelper41   AudioState::Config& config() { return audio_state_config; }
mixerwebrtc::test::__anon970564350111::ConfigHelper42   rtc::scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
43 
44  private:
45   AudioState::Config audio_state_config;
46   rtc::scoped_refptr<AudioMixer> audio_mixer;
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 
Create10msTestData(int sample_rate_hz,size_t num_channels)63 std::vector<int16_t> Create10msTestData(int sample_rate_hz,
64                                         size_t num_channels) {
65   const int samples_per_channel = sample_rate_hz / 100;
66   std::vector<int16_t> audio_data(samples_per_channel * num_channels, 0);
67   // Fill the first channel with a 1kHz sine wave.
68   const float inc = (2 * 3.14159265f * 1000) / sample_rate_hz;
69   float w = 0.f;
70   for (int i = 0; i < samples_per_channel; ++i) {
71     audio_data[i * num_channels] = static_cast<int16_t>(32767.f * std::sin(w));
72     w += inc;
73   }
74   return audio_data;
75 }
76 
ComputeChannelLevels(AudioFrame * audio_frame)77 std::vector<uint32_t> ComputeChannelLevels(AudioFrame* audio_frame) {
78   const size_t num_channels = audio_frame->num_channels_;
79   const size_t samples_per_channel = audio_frame->samples_per_channel_;
80   std::vector<uint32_t> levels(num_channels, 0);
81   for (size_t i = 0; i < samples_per_channel; ++i) {
82     for (size_t j = 0; j < num_channels; ++j) {
83       levels[j] += std::abs(audio_frame->data()[i * num_channels + j]);
84     }
85   }
86   return levels;
87 }
88 }  // namespace
89 
TEST(AudioStateTest,Create)90 TEST(AudioStateTest, Create) {
91   ConfigHelper helper;
92   auto audio_state = AudioState::Create(helper.config());
93   EXPECT_TRUE(audio_state.get());
94 }
95 
TEST(AudioStateTest,ConstructDestruct)96 TEST(AudioStateTest, ConstructDestruct) {
97   ConfigHelper helper;
98   rtc::scoped_refptr<internal::AudioState> audio_state(
99       new rtc::RefCountedObject<internal::AudioState>(helper.config()));
100 }
101 
TEST(AudioStateTest,RecordedAudioArrivesAtSingleStream)102 TEST(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
103   ConfigHelper helper;
104   rtc::scoped_refptr<internal::AudioState> audio_state(
105       new rtc::RefCountedObject<internal::AudioState>(helper.config()));
106 
107   MockAudioSendStream stream;
108   audio_state->AddSendingStream(&stream, 8000, 2);
109 
110   EXPECT_CALL(
111       stream,
112       SendAudioDataForMock(::testing::AllOf(
113           ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(8000)),
114           ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(2u)))))
115       .WillOnce(
116           // Verify that channels are not swapped by default.
117           ::testing::Invoke([](AudioFrame* audio_frame) {
118             auto levels = ComputeChannelLevels(audio_frame);
119             EXPECT_LT(0u, levels[0]);
120             EXPECT_EQ(0u, levels[1]);
121           }));
122   MockAudioProcessing* ap =
123       static_cast<MockAudioProcessing*>(audio_state->audio_processing());
124   EXPECT_CALL(*ap, set_stream_delay_ms(0));
125   EXPECT_CALL(*ap, set_stream_key_pressed(false));
126   EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
127 
128   constexpr int kSampleRate = 16000;
129   constexpr size_t kNumChannels = 2;
130   auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
131   uint32_t new_mic_level = 667;
132   audio_state->audio_transport()->RecordedDataIsAvailable(
133       &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
134       kSampleRate, 0, 0, 0, false, new_mic_level);
135   EXPECT_EQ(667u, new_mic_level);
136 
137   audio_state->RemoveSendingStream(&stream);
138 }
139 
TEST(AudioStateTest,RecordedAudioArrivesAtMultipleStreams)140 TEST(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
141   ConfigHelper helper;
142   rtc::scoped_refptr<internal::AudioState> audio_state(
143       new rtc::RefCountedObject<internal::AudioState>(helper.config()));
144 
145   MockAudioSendStream stream_1;
146   MockAudioSendStream stream_2;
147   audio_state->AddSendingStream(&stream_1, 8001, 2);
148   audio_state->AddSendingStream(&stream_2, 32000, 1);
149 
150   EXPECT_CALL(
151       stream_1,
152       SendAudioDataForMock(::testing::AllOf(
153           ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
154           ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
155       .WillOnce(
156           // Verify that there is output signal.
157           ::testing::Invoke([](AudioFrame* audio_frame) {
158             auto levels = ComputeChannelLevels(audio_frame);
159             EXPECT_LT(0u, levels[0]);
160           }));
161   EXPECT_CALL(
162       stream_2,
163       SendAudioDataForMock(::testing::AllOf(
164           ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
165           ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
166       .WillOnce(
167           // Verify that there is output signal.
168           ::testing::Invoke([](AudioFrame* audio_frame) {
169             auto levels = ComputeChannelLevels(audio_frame);
170             EXPECT_LT(0u, levels[0]);
171           }));
172   MockAudioProcessing* ap =
173       static_cast<MockAudioProcessing*>(audio_state->audio_processing());
174   EXPECT_CALL(*ap, set_stream_delay_ms(5));
175   EXPECT_CALL(*ap, set_stream_key_pressed(true));
176   EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
177 
178   constexpr int kSampleRate = 16000;
179   constexpr size_t kNumChannels = 1;
180   auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
181   uint32_t new_mic_level = 667;
182   audio_state->audio_transport()->RecordedDataIsAvailable(
183       &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
184       kSampleRate, 5, 0, 0, true, new_mic_level);
185   EXPECT_EQ(667u, new_mic_level);
186 
187   audio_state->RemoveSendingStream(&stream_1);
188   audio_state->RemoveSendingStream(&stream_2);
189 }
190 
TEST(AudioStateTest,EnableChannelSwap)191 TEST(AudioStateTest, EnableChannelSwap) {
192   constexpr int kSampleRate = 16000;
193   constexpr size_t kNumChannels = 2;
194 
195   ConfigHelper helper;
196   rtc::scoped_refptr<internal::AudioState> audio_state(
197       new rtc::RefCountedObject<internal::AudioState>(helper.config()));
198 
199   audio_state->SetStereoChannelSwapping(true);
200 
201   MockAudioSendStream stream;
202   audio_state->AddSendingStream(&stream, kSampleRate, kNumChannels);
203 
204   EXPECT_CALL(stream, SendAudioDataForMock(_))
205       .WillOnce(
206           // Verify that channels are swapped.
207           ::testing::Invoke([](AudioFrame* audio_frame) {
208             auto levels = ComputeChannelLevels(audio_frame);
209             EXPECT_EQ(0u, levels[0]);
210             EXPECT_LT(0u, levels[1]);
211           }));
212 
213   auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
214   uint32_t new_mic_level = 667;
215   audio_state->audio_transport()->RecordedDataIsAvailable(
216       &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
217       kSampleRate, 0, 0, 0, false, new_mic_level);
218   EXPECT_EQ(667u, new_mic_level);
219 
220   audio_state->RemoveSendingStream(&stream);
221 }
222 
TEST(AudioStateTest,QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource)223 TEST(AudioStateTest,
224      QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource) {
225   ConfigHelper helper;
226   auto audio_state = AudioState::Create(helper.config());
227 
228   FakeAudioSource fake_source;
229   helper.mixer()->AddSource(&fake_source);
230 
231   EXPECT_CALL(fake_source, GetAudioFrameWithInfo(_, _))
232       .WillOnce(
233           ::testing::Invoke([](int sample_rate_hz, AudioFrame* audio_frame) {
234             audio_frame->sample_rate_hz_ = sample_rate_hz;
235             audio_frame->samples_per_channel_ = sample_rate_hz / 100;
236             audio_frame->num_channels_ = kNumberOfChannels;
237             return AudioMixer::Source::AudioFrameInfo::kNormal;
238           }));
239 
240   int16_t audio_buffer[kSampleRate / 100 * kNumberOfChannels];
241   size_t n_samples_out;
242   int64_t elapsed_time_ms;
243   int64_t ntp_time_ms;
244   audio_state->audio_transport()->NeedMorePlayData(
245       kSampleRate / 100, kNumberOfChannels * 2, kNumberOfChannels, kSampleRate,
246       audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
247 }
248 }  // namespace test
249 }  // namespace webrtc
250