1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_state.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <utility>
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker
17*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/test/mock_task_queue_base.h"
18*d9f75844SAndroid Build Coastguard Worker #include "call/test/mock_audio_send_stream.h"
19*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/mock_audio_device.h"
20*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_mixer/audio_mixer_impl.h"
21*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/mock_audio_processing.h"
22*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
23*d9f75844SAndroid Build Coastguard Worker
24*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
25*d9f75844SAndroid Build Coastguard Worker namespace test {
26*d9f75844SAndroid Build Coastguard Worker namespace {
27*d9f75844SAndroid Build Coastguard Worker
28*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
29*d9f75844SAndroid Build Coastguard Worker using ::testing::Matcher;
30*d9f75844SAndroid Build Coastguard Worker using ::testing::NiceMock;
31*d9f75844SAndroid Build Coastguard Worker using ::testing::StrictMock;
32*d9f75844SAndroid Build Coastguard Worker using ::testing::Values;
33*d9f75844SAndroid Build Coastguard Worker
34*d9f75844SAndroid Build Coastguard Worker constexpr int kSampleRate = 16000;
35*d9f75844SAndroid Build Coastguard Worker constexpr int kNumberOfChannels = 1;
36*d9f75844SAndroid Build Coastguard Worker
37*d9f75844SAndroid Build Coastguard Worker struct FakeAsyncAudioProcessingHelper {
38*d9f75844SAndroid Build Coastguard Worker class FakeTaskQueue : public StrictMock<MockTaskQueueBase> {
39*d9f75844SAndroid Build Coastguard Worker public:
40*d9f75844SAndroid Build Coastguard Worker FakeTaskQueue() = default;
41*d9f75844SAndroid Build Coastguard Worker
Delete()42*d9f75844SAndroid Build Coastguard Worker void Delete() override { delete this; }
PostTask(absl::AnyInvocable<void ()&&> task)43*d9f75844SAndroid Build Coastguard Worker void PostTask(absl::AnyInvocable<void() &&> task) override {
44*d9f75844SAndroid Build Coastguard Worker std::move(task)();
45*d9f75844SAndroid Build Coastguard Worker }
46*d9f75844SAndroid Build Coastguard Worker };
47*d9f75844SAndroid Build Coastguard Worker
48*d9f75844SAndroid Build Coastguard Worker class FakeTaskQueueFactory : public TaskQueueFactory {
49*d9f75844SAndroid Build Coastguard Worker public:
50*d9f75844SAndroid Build Coastguard Worker FakeTaskQueueFactory() = default;
51*d9f75844SAndroid Build Coastguard Worker ~FakeTaskQueueFactory() override = default;
CreateTaskQueue(absl::string_view name,Priority priority) const52*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
53*d9f75844SAndroid Build Coastguard Worker absl::string_view name,
54*d9f75844SAndroid Build Coastguard Worker Priority priority) const override {
55*d9f75844SAndroid Build Coastguard Worker return std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>(
56*d9f75844SAndroid Build Coastguard Worker new FakeTaskQueue());
57*d9f75844SAndroid Build Coastguard Worker }
58*d9f75844SAndroid Build Coastguard Worker };
59*d9f75844SAndroid Build Coastguard Worker
60*d9f75844SAndroid Build Coastguard Worker class MockAudioFrameProcessor : public AudioFrameProcessor {
61*d9f75844SAndroid Build Coastguard Worker public:
62*d9f75844SAndroid Build Coastguard Worker ~MockAudioFrameProcessor() override = default;
63*d9f75844SAndroid Build Coastguard Worker
64*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(void, ProcessCalled, ());
65*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(void, SinkSet, ());
66*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(void, SinkCleared, ());
67*d9f75844SAndroid Build Coastguard Worker
Process(std::unique_ptr<AudioFrame> frame)68*d9f75844SAndroid Build Coastguard Worker void Process(std::unique_ptr<AudioFrame> frame) override {
69*d9f75844SAndroid Build Coastguard Worker ProcessCalled();
70*d9f75844SAndroid Build Coastguard Worker sink_callback_(std::move(frame));
71*d9f75844SAndroid Build Coastguard Worker }
72*d9f75844SAndroid Build Coastguard Worker
SetSink(OnAudioFrameCallback sink_callback)73*d9f75844SAndroid Build Coastguard Worker void SetSink(OnAudioFrameCallback sink_callback) override {
74*d9f75844SAndroid Build Coastguard Worker sink_callback_ = std::move(sink_callback);
75*d9f75844SAndroid Build Coastguard Worker if (sink_callback_ == nullptr)
76*d9f75844SAndroid Build Coastguard Worker SinkCleared();
77*d9f75844SAndroid Build Coastguard Worker else
78*d9f75844SAndroid Build Coastguard Worker SinkSet();
79*d9f75844SAndroid Build Coastguard Worker }
80*d9f75844SAndroid Build Coastguard Worker
81*d9f75844SAndroid Build Coastguard Worker private:
82*d9f75844SAndroid Build Coastguard Worker OnAudioFrameCallback sink_callback_;
83*d9f75844SAndroid Build Coastguard Worker };
84*d9f75844SAndroid Build Coastguard Worker
85*d9f75844SAndroid Build Coastguard Worker NiceMock<MockAudioFrameProcessor> audio_frame_processor_;
86*d9f75844SAndroid Build Coastguard Worker FakeTaskQueueFactory task_queue_factory_;
87*d9f75844SAndroid Build Coastguard Worker
CreateFactorywebrtc::test::__anon7c853fc30111::FakeAsyncAudioProcessingHelper88*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AsyncAudioProcessing::Factory> CreateFactory() {
89*d9f75844SAndroid Build Coastguard Worker return rtc::make_ref_counted<AsyncAudioProcessing::Factory>(
90*d9f75844SAndroid Build Coastguard Worker audio_frame_processor_, task_queue_factory_);
91*d9f75844SAndroid Build Coastguard Worker }
92*d9f75844SAndroid Build Coastguard Worker };
93*d9f75844SAndroid Build Coastguard Worker
94*d9f75844SAndroid Build Coastguard Worker struct ConfigHelper {
95*d9f75844SAndroid Build Coastguard Worker struct Params {
96*d9f75844SAndroid Build Coastguard Worker bool use_null_audio_processing;
97*d9f75844SAndroid Build Coastguard Worker bool use_async_audio_processing;
98*d9f75844SAndroid Build Coastguard Worker };
99*d9f75844SAndroid Build Coastguard Worker
ConfigHelperwebrtc::test::__anon7c853fc30111::ConfigHelper100*d9f75844SAndroid Build Coastguard Worker explicit ConfigHelper(const Params& params)
101*d9f75844SAndroid Build Coastguard Worker : audio_mixer(AudioMixerImpl::Create()) {
102*d9f75844SAndroid Build Coastguard Worker audio_state_config.audio_mixer = audio_mixer;
103*d9f75844SAndroid Build Coastguard Worker audio_state_config.audio_processing =
104*d9f75844SAndroid Build Coastguard Worker params.use_null_audio_processing
105*d9f75844SAndroid Build Coastguard Worker ? nullptr
106*d9f75844SAndroid Build Coastguard Worker : rtc::make_ref_counted<testing::NiceMock<MockAudioProcessing>>();
107*d9f75844SAndroid Build Coastguard Worker audio_state_config.audio_device_module =
108*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<NiceMock<MockAudioDeviceModule>>();
109*d9f75844SAndroid Build Coastguard Worker if (params.use_async_audio_processing) {
110*d9f75844SAndroid Build Coastguard Worker audio_state_config.async_audio_processing_factory =
111*d9f75844SAndroid Build Coastguard Worker async_audio_processing_helper_.CreateFactory();
112*d9f75844SAndroid Build Coastguard Worker }
113*d9f75844SAndroid Build Coastguard Worker }
configwebrtc::test::__anon7c853fc30111::ConfigHelper114*d9f75844SAndroid Build Coastguard Worker AudioState::Config& config() { return audio_state_config; }
mixerwebrtc::test::__anon7c853fc30111::ConfigHelper115*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
116*d9f75844SAndroid Build Coastguard Worker NiceMock<FakeAsyncAudioProcessingHelper::MockAudioFrameProcessor>&
mock_audio_frame_processorwebrtc::test::__anon7c853fc30111::ConfigHelper117*d9f75844SAndroid Build Coastguard Worker mock_audio_frame_processor() {
118*d9f75844SAndroid Build Coastguard Worker return async_audio_processing_helper_.audio_frame_processor_;
119*d9f75844SAndroid Build Coastguard Worker }
120*d9f75844SAndroid Build Coastguard Worker
121*d9f75844SAndroid Build Coastguard Worker private:
122*d9f75844SAndroid Build Coastguard Worker AudioState::Config audio_state_config;
123*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioMixer> audio_mixer;
124*d9f75844SAndroid Build Coastguard Worker FakeAsyncAudioProcessingHelper async_audio_processing_helper_;
125*d9f75844SAndroid Build Coastguard Worker };
126*d9f75844SAndroid Build Coastguard Worker
127*d9f75844SAndroid Build Coastguard Worker class FakeAudioSource : public AudioMixer::Source {
128*d9f75844SAndroid Build Coastguard Worker public:
129*d9f75844SAndroid Build Coastguard Worker // TODO(aleloi): Valid overrides commented out, because the gmock
130*d9f75844SAndroid Build Coastguard Worker // methods don't use any override declarations, and we want to avoid
131*d9f75844SAndroid Build Coastguard Worker // warnings from -Winconsistent-missing-override. See
132*d9f75844SAndroid Build Coastguard Worker // http://crbug.com/428099.
Ssrc() const133*d9f75844SAndroid Build Coastguard Worker int Ssrc() const /*override*/ { return 0; }
134*d9f75844SAndroid Build Coastguard Worker
PreferredSampleRate() const135*d9f75844SAndroid Build Coastguard Worker int PreferredSampleRate() const /*override*/ { return kSampleRate; }
136*d9f75844SAndroid Build Coastguard Worker
137*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(AudioFrameInfo,
138*d9f75844SAndroid Build Coastguard Worker GetAudioFrameWithInfo,
139*d9f75844SAndroid Build Coastguard Worker (int sample_rate_hz, AudioFrame*),
140*d9f75844SAndroid Build Coastguard Worker (override));
141*d9f75844SAndroid Build Coastguard Worker };
142*d9f75844SAndroid Build Coastguard Worker
Create10msTestData(int sample_rate_hz,size_t num_channels)143*d9f75844SAndroid Build Coastguard Worker std::vector<int16_t> Create10msTestData(int sample_rate_hz,
144*d9f75844SAndroid Build Coastguard Worker size_t num_channels) {
145*d9f75844SAndroid Build Coastguard Worker const int samples_per_channel = sample_rate_hz / 100;
146*d9f75844SAndroid Build Coastguard Worker std::vector<int16_t> audio_data(samples_per_channel * num_channels, 0);
147*d9f75844SAndroid Build Coastguard Worker // Fill the first channel with a 1kHz sine wave.
148*d9f75844SAndroid Build Coastguard Worker const float inc = (2 * 3.14159265f * 1000) / sample_rate_hz;
149*d9f75844SAndroid Build Coastguard Worker float w = 0.f;
150*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < samples_per_channel; ++i) {
151*d9f75844SAndroid Build Coastguard Worker audio_data[i * num_channels] = static_cast<int16_t>(32767.f * std::sin(w));
152*d9f75844SAndroid Build Coastguard Worker w += inc;
153*d9f75844SAndroid Build Coastguard Worker }
154*d9f75844SAndroid Build Coastguard Worker return audio_data;
155*d9f75844SAndroid Build Coastguard Worker }
156*d9f75844SAndroid Build Coastguard Worker
ComputeChannelLevels(AudioFrame * audio_frame)157*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ComputeChannelLevels(AudioFrame* audio_frame) {
158*d9f75844SAndroid Build Coastguard Worker const size_t num_channels = audio_frame->num_channels_;
159*d9f75844SAndroid Build Coastguard Worker const size_t samples_per_channel = audio_frame->samples_per_channel_;
160*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> levels(num_channels, 0);
161*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < samples_per_channel; ++i) {
162*d9f75844SAndroid Build Coastguard Worker for (size_t j = 0; j < num_channels; ++j) {
163*d9f75844SAndroid Build Coastguard Worker levels[j] += std::abs(audio_frame->data()[i * num_channels + j]);
164*d9f75844SAndroid Build Coastguard Worker }
165*d9f75844SAndroid Build Coastguard Worker }
166*d9f75844SAndroid Build Coastguard Worker return levels;
167*d9f75844SAndroid Build Coastguard Worker }
168*d9f75844SAndroid Build Coastguard Worker } // namespace
169*d9f75844SAndroid Build Coastguard Worker
170*d9f75844SAndroid Build Coastguard Worker class AudioStateTest : public ::testing::TestWithParam<ConfigHelper::Params> {};
171*d9f75844SAndroid Build Coastguard Worker
TEST_P(AudioStateTest,Create)172*d9f75844SAndroid Build Coastguard Worker TEST_P(AudioStateTest, Create) {
173*d9f75844SAndroid Build Coastguard Worker ConfigHelper helper(GetParam());
174*d9f75844SAndroid Build Coastguard Worker auto audio_state = AudioState::Create(helper.config());
175*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_state.get());
176*d9f75844SAndroid Build Coastguard Worker }
177*d9f75844SAndroid Build Coastguard Worker
TEST_P(AudioStateTest,ConstructDestruct)178*d9f75844SAndroid Build Coastguard Worker TEST_P(AudioStateTest, ConstructDestruct) {
179*d9f75844SAndroid Build Coastguard Worker ConfigHelper helper(GetParam());
180*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<internal::AudioState> audio_state(
181*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<internal::AudioState>(helper.config()));
182*d9f75844SAndroid Build Coastguard Worker }
183*d9f75844SAndroid Build Coastguard Worker
TEST_P(AudioStateTest,RecordedAudioArrivesAtSingleStream)184*d9f75844SAndroid Build Coastguard Worker TEST_P(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
185*d9f75844SAndroid Build Coastguard Worker ConfigHelper helper(GetParam());
186*d9f75844SAndroid Build Coastguard Worker
187*d9f75844SAndroid Build Coastguard Worker if (GetParam().use_async_audio_processing) {
188*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), SinkSet);
189*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), ProcessCalled);
190*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), SinkCleared);
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker
193*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<internal::AudioState> audio_state(
194*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<internal::AudioState>(helper.config()));
195*d9f75844SAndroid Build Coastguard Worker
196*d9f75844SAndroid Build Coastguard Worker MockAudioSendStream stream;
197*d9f75844SAndroid Build Coastguard Worker audio_state->AddSendingStream(&stream, 8000, 2);
198*d9f75844SAndroid Build Coastguard Worker
199*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(
200*d9f75844SAndroid Build Coastguard Worker stream,
201*d9f75844SAndroid Build Coastguard Worker SendAudioDataForMock(::testing::AllOf(
202*d9f75844SAndroid Build Coastguard Worker ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(8000)),
203*d9f75844SAndroid Build Coastguard Worker ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(2u)))))
204*d9f75844SAndroid Build Coastguard Worker .WillOnce(
205*d9f75844SAndroid Build Coastguard Worker // Verify that channels are not swapped by default.
206*d9f75844SAndroid Build Coastguard Worker ::testing::Invoke([](AudioFrame* audio_frame) {
207*d9f75844SAndroid Build Coastguard Worker auto levels = ComputeChannelLevels(audio_frame);
208*d9f75844SAndroid Build Coastguard Worker EXPECT_LT(0u, levels[0]);
209*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, levels[1]);
210*d9f75844SAndroid Build Coastguard Worker }));
211*d9f75844SAndroid Build Coastguard Worker MockAudioProcessing* ap =
212*d9f75844SAndroid Build Coastguard Worker GetParam().use_null_audio_processing
213*d9f75844SAndroid Build Coastguard Worker ? nullptr
214*d9f75844SAndroid Build Coastguard Worker : static_cast<MockAudioProcessing*>(audio_state->audio_processing());
215*d9f75844SAndroid Build Coastguard Worker if (ap) {
216*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*ap, set_stream_delay_ms(0));
217*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*ap, set_stream_key_pressed(false));
218*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
219*d9f75844SAndroid Build Coastguard Worker }
220*d9f75844SAndroid Build Coastguard Worker
221*d9f75844SAndroid Build Coastguard Worker constexpr int kSampleRate = 16000;
222*d9f75844SAndroid Build Coastguard Worker constexpr size_t kNumChannels = 2;
223*d9f75844SAndroid Build Coastguard Worker auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
224*d9f75844SAndroid Build Coastguard Worker uint32_t new_mic_level = 667;
225*d9f75844SAndroid Build Coastguard Worker audio_state->audio_transport()->RecordedDataIsAvailable(
226*d9f75844SAndroid Build Coastguard Worker &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
227*d9f75844SAndroid Build Coastguard Worker kSampleRate, 0, 0, 0, false, new_mic_level);
228*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(667u, new_mic_level);
229*d9f75844SAndroid Build Coastguard Worker
230*d9f75844SAndroid Build Coastguard Worker audio_state->RemoveSendingStream(&stream);
231*d9f75844SAndroid Build Coastguard Worker }
232*d9f75844SAndroid Build Coastguard Worker
TEST_P(AudioStateTest,RecordedAudioArrivesAtMultipleStreams)233*d9f75844SAndroid Build Coastguard Worker TEST_P(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
234*d9f75844SAndroid Build Coastguard Worker ConfigHelper helper(GetParam());
235*d9f75844SAndroid Build Coastguard Worker
236*d9f75844SAndroid Build Coastguard Worker if (GetParam().use_async_audio_processing) {
237*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), SinkSet);
238*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), ProcessCalled);
239*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), SinkCleared);
240*d9f75844SAndroid Build Coastguard Worker }
241*d9f75844SAndroid Build Coastguard Worker
242*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<internal::AudioState> audio_state(
243*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<internal::AudioState>(helper.config()));
244*d9f75844SAndroid Build Coastguard Worker
245*d9f75844SAndroid Build Coastguard Worker MockAudioSendStream stream_1;
246*d9f75844SAndroid Build Coastguard Worker MockAudioSendStream stream_2;
247*d9f75844SAndroid Build Coastguard Worker audio_state->AddSendingStream(&stream_1, 8001, 2);
248*d9f75844SAndroid Build Coastguard Worker audio_state->AddSendingStream(&stream_2, 32000, 1);
249*d9f75844SAndroid Build Coastguard Worker
250*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(
251*d9f75844SAndroid Build Coastguard Worker stream_1,
252*d9f75844SAndroid Build Coastguard Worker SendAudioDataForMock(::testing::AllOf(
253*d9f75844SAndroid Build Coastguard Worker ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
254*d9f75844SAndroid Build Coastguard Worker ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
255*d9f75844SAndroid Build Coastguard Worker .WillOnce(
256*d9f75844SAndroid Build Coastguard Worker // Verify that there is output signal.
257*d9f75844SAndroid Build Coastguard Worker ::testing::Invoke([](AudioFrame* audio_frame) {
258*d9f75844SAndroid Build Coastguard Worker auto levels = ComputeChannelLevels(audio_frame);
259*d9f75844SAndroid Build Coastguard Worker EXPECT_LT(0u, levels[0]);
260*d9f75844SAndroid Build Coastguard Worker }));
261*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(
262*d9f75844SAndroid Build Coastguard Worker stream_2,
263*d9f75844SAndroid Build Coastguard Worker SendAudioDataForMock(::testing::AllOf(
264*d9f75844SAndroid Build Coastguard Worker ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
265*d9f75844SAndroid Build Coastguard Worker ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
266*d9f75844SAndroid Build Coastguard Worker .WillOnce(
267*d9f75844SAndroid Build Coastguard Worker // Verify that there is output signal.
268*d9f75844SAndroid Build Coastguard Worker ::testing::Invoke([](AudioFrame* audio_frame) {
269*d9f75844SAndroid Build Coastguard Worker auto levels = ComputeChannelLevels(audio_frame);
270*d9f75844SAndroid Build Coastguard Worker EXPECT_LT(0u, levels[0]);
271*d9f75844SAndroid Build Coastguard Worker }));
272*d9f75844SAndroid Build Coastguard Worker MockAudioProcessing* ap =
273*d9f75844SAndroid Build Coastguard Worker static_cast<MockAudioProcessing*>(audio_state->audio_processing());
274*d9f75844SAndroid Build Coastguard Worker if (ap) {
275*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*ap, set_stream_delay_ms(5));
276*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*ap, set_stream_key_pressed(true));
277*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
278*d9f75844SAndroid Build Coastguard Worker }
279*d9f75844SAndroid Build Coastguard Worker
280*d9f75844SAndroid Build Coastguard Worker constexpr int kSampleRate = 16000;
281*d9f75844SAndroid Build Coastguard Worker constexpr size_t kNumChannels = 1;
282*d9f75844SAndroid Build Coastguard Worker auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
283*d9f75844SAndroid Build Coastguard Worker uint32_t new_mic_level = 667;
284*d9f75844SAndroid Build Coastguard Worker audio_state->audio_transport()->RecordedDataIsAvailable(
285*d9f75844SAndroid Build Coastguard Worker &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
286*d9f75844SAndroid Build Coastguard Worker kSampleRate, 5, 0, 0, true, new_mic_level);
287*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(667u, new_mic_level);
288*d9f75844SAndroid Build Coastguard Worker
289*d9f75844SAndroid Build Coastguard Worker audio_state->RemoveSendingStream(&stream_1);
290*d9f75844SAndroid Build Coastguard Worker audio_state->RemoveSendingStream(&stream_2);
291*d9f75844SAndroid Build Coastguard Worker }
292*d9f75844SAndroid Build Coastguard Worker
TEST_P(AudioStateTest,EnableChannelSwap)293*d9f75844SAndroid Build Coastguard Worker TEST_P(AudioStateTest, EnableChannelSwap) {
294*d9f75844SAndroid Build Coastguard Worker constexpr int kSampleRate = 16000;
295*d9f75844SAndroid Build Coastguard Worker constexpr size_t kNumChannels = 2;
296*d9f75844SAndroid Build Coastguard Worker
297*d9f75844SAndroid Build Coastguard Worker ConfigHelper helper(GetParam());
298*d9f75844SAndroid Build Coastguard Worker
299*d9f75844SAndroid Build Coastguard Worker if (GetParam().use_async_audio_processing) {
300*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), SinkSet);
301*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), ProcessCalled);
302*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(helper.mock_audio_frame_processor(), SinkCleared);
303*d9f75844SAndroid Build Coastguard Worker }
304*d9f75844SAndroid Build Coastguard Worker
305*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<internal::AudioState> audio_state(
306*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<internal::AudioState>(helper.config()));
307*d9f75844SAndroid Build Coastguard Worker
308*d9f75844SAndroid Build Coastguard Worker audio_state->SetStereoChannelSwapping(true);
309*d9f75844SAndroid Build Coastguard Worker
310*d9f75844SAndroid Build Coastguard Worker MockAudioSendStream stream;
311*d9f75844SAndroid Build Coastguard Worker audio_state->AddSendingStream(&stream, kSampleRate, kNumChannels);
312*d9f75844SAndroid Build Coastguard Worker
313*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stream, SendAudioDataForMock(_))
314*d9f75844SAndroid Build Coastguard Worker .WillOnce(
315*d9f75844SAndroid Build Coastguard Worker // Verify that channels are swapped.
316*d9f75844SAndroid Build Coastguard Worker ::testing::Invoke([](AudioFrame* audio_frame) {
317*d9f75844SAndroid Build Coastguard Worker auto levels = ComputeChannelLevels(audio_frame);
318*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0u, levels[0]);
319*d9f75844SAndroid Build Coastguard Worker EXPECT_LT(0u, levels[1]);
320*d9f75844SAndroid Build Coastguard Worker }));
321*d9f75844SAndroid Build Coastguard Worker
322*d9f75844SAndroid Build Coastguard Worker auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
323*d9f75844SAndroid Build Coastguard Worker uint32_t new_mic_level = 667;
324*d9f75844SAndroid Build Coastguard Worker audio_state->audio_transport()->RecordedDataIsAvailable(
325*d9f75844SAndroid Build Coastguard Worker &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
326*d9f75844SAndroid Build Coastguard Worker kSampleRate, 0, 0, 0, false, new_mic_level);
327*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(667u, new_mic_level);
328*d9f75844SAndroid Build Coastguard Worker
329*d9f75844SAndroid Build Coastguard Worker audio_state->RemoveSendingStream(&stream);
330*d9f75844SAndroid Build Coastguard Worker }
331*d9f75844SAndroid Build Coastguard Worker
TEST_P(AudioStateTest,QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource)332*d9f75844SAndroid Build Coastguard Worker TEST_P(AudioStateTest,
333*d9f75844SAndroid Build Coastguard Worker QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource) {
334*d9f75844SAndroid Build Coastguard Worker ConfigHelper helper(GetParam());
335*d9f75844SAndroid Build Coastguard Worker auto audio_state = AudioState::Create(helper.config());
336*d9f75844SAndroid Build Coastguard Worker
337*d9f75844SAndroid Build Coastguard Worker FakeAudioSource fake_source;
338*d9f75844SAndroid Build Coastguard Worker helper.mixer()->AddSource(&fake_source);
339*d9f75844SAndroid Build Coastguard Worker
340*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(fake_source, GetAudioFrameWithInfo(_, _))
341*d9f75844SAndroid Build Coastguard Worker .WillOnce(
342*d9f75844SAndroid Build Coastguard Worker ::testing::Invoke([](int sample_rate_hz, AudioFrame* audio_frame) {
343*d9f75844SAndroid Build Coastguard Worker audio_frame->sample_rate_hz_ = sample_rate_hz;
344*d9f75844SAndroid Build Coastguard Worker audio_frame->samples_per_channel_ = sample_rate_hz / 100;
345*d9f75844SAndroid Build Coastguard Worker audio_frame->num_channels_ = kNumberOfChannels;
346*d9f75844SAndroid Build Coastguard Worker return AudioMixer::Source::AudioFrameInfo::kNormal;
347*d9f75844SAndroid Build Coastguard Worker }));
348*d9f75844SAndroid Build Coastguard Worker
349*d9f75844SAndroid Build Coastguard Worker int16_t audio_buffer[kSampleRate / 100 * kNumberOfChannels];
350*d9f75844SAndroid Build Coastguard Worker size_t n_samples_out;
351*d9f75844SAndroid Build Coastguard Worker int64_t elapsed_time_ms;
352*d9f75844SAndroid Build Coastguard Worker int64_t ntp_time_ms;
353*d9f75844SAndroid Build Coastguard Worker audio_state->audio_transport()->NeedMorePlayData(
354*d9f75844SAndroid Build Coastguard Worker kSampleRate / 100, kNumberOfChannels * 2, kNumberOfChannels, kSampleRate,
355*d9f75844SAndroid Build Coastguard Worker audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
356*d9f75844SAndroid Build Coastguard Worker }
357*d9f75844SAndroid Build Coastguard Worker
358*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(AudioStateTest,
359*d9f75844SAndroid Build Coastguard Worker AudioStateTest,
360*d9f75844SAndroid Build Coastguard Worker Values(ConfigHelper::Params({false, false}),
361*d9f75844SAndroid Build Coastguard Worker ConfigHelper::Params({true, false}),
362*d9f75844SAndroid Build Coastguard Worker ConfigHelper::Params({false, true}),
363*d9f75844SAndroid Build Coastguard Worker ConfigHelper::Params({true, true})));
364*d9f75844SAndroid Build Coastguard Worker
365*d9f75844SAndroid Build Coastguard Worker } // namespace test
366*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
367