xref: /aosp_15_r20/external/webrtc/audio/audio_state_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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