xref: /aosp_15_r20/external/webrtc/audio/voip/test/audio_ingress_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2020 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/voip/audio_ingress.h"
12 
13 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
14 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
15 #include "api/call/transport.h"
16 #include "api/task_queue/default_task_queue_factory.h"
17 #include "audio/voip/audio_egress.h"
18 #include "modules/audio_mixer/sine_wave_generator.h"
19 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
20 #include "rtc_base/event.h"
21 #include "rtc_base/logging.h"
22 #include "test/gmock.h"
23 #include "test/gtest.h"
24 #include "test/mock_transport.h"
25 #include "test/run_loop.h"
26 
27 namespace webrtc {
28 namespace {
29 
30 using ::testing::Invoke;
31 using ::testing::NiceMock;
32 using ::testing::Unused;
33 
34 constexpr int16_t kAudioLevel = 3004;  // Used for sine wave level.
35 
36 class AudioIngressTest : public ::testing::Test {
37  public:
38   const SdpAudioFormat kPcmuFormat = {"pcmu", 8000, 1};
39 
AudioIngressTest()40   AudioIngressTest()
41       : fake_clock_(123456789), wave_generator_(1000.0, kAudioLevel) {
42     receive_statistics_ = ReceiveStatistics::Create(&fake_clock_);
43 
44     RtpRtcpInterface::Configuration rtp_config;
45     rtp_config.clock = &fake_clock_;
46     rtp_config.audio = true;
47     rtp_config.receive_statistics = receive_statistics_.get();
48     rtp_config.rtcp_report_interval_ms = 5000;
49     rtp_config.outgoing_transport = &transport_;
50     rtp_config.local_media_ssrc = 0xdeadc0de;
51     rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(rtp_config);
52 
53     rtp_rtcp_->SetSendingMediaStatus(false);
54     rtp_rtcp_->SetRTCPStatus(RtcpMode::kCompound);
55 
56     task_queue_factory_ = CreateDefaultTaskQueueFactory();
57     encoder_factory_ = CreateBuiltinAudioEncoderFactory();
58     decoder_factory_ = CreateBuiltinAudioDecoderFactory();
59   }
60 
SetUp()61   void SetUp() override {
62     constexpr int kPcmuPayload = 0;
63     ingress_ = std::make_unique<AudioIngress>(rtp_rtcp_.get(), &fake_clock_,
64                                               receive_statistics_.get(),
65                                               decoder_factory_);
66     ingress_->SetReceiveCodecs({{kPcmuPayload, kPcmuFormat}});
67 
68     egress_ = std::make_unique<AudioEgress>(rtp_rtcp_.get(), &fake_clock_,
69                                             task_queue_factory_.get());
70     egress_->SetEncoder(kPcmuPayload, kPcmuFormat,
71                         encoder_factory_->MakeAudioEncoder(
72                             kPcmuPayload, kPcmuFormat, absl::nullopt));
73     egress_->StartSend();
74     ingress_->StartPlay();
75     rtp_rtcp_->SetSendingStatus(true);
76   }
77 
TearDown()78   void TearDown() override {
79     rtp_rtcp_->SetSendingStatus(false);
80     ingress_->StopPlay();
81     egress_->StopSend();
82     egress_.reset();
83     ingress_.reset();
84   }
85 
GetAudioFrame(int order)86   std::unique_ptr<AudioFrame> GetAudioFrame(int order) {
87     auto frame = std::make_unique<AudioFrame>();
88     frame->sample_rate_hz_ = kPcmuFormat.clockrate_hz;
89     frame->samples_per_channel_ = kPcmuFormat.clockrate_hz / 100;  // 10 ms.
90     frame->num_channels_ = kPcmuFormat.num_channels;
91     frame->timestamp_ = frame->samples_per_channel_ * order;
92     wave_generator_.GenerateNextFrame(frame.get());
93     return frame;
94   }
95 
96   test::RunLoop run_loop_;
97   SimulatedClock fake_clock_;
98   SineWaveGenerator wave_generator_;
99   NiceMock<MockTransport> transport_;
100   std::unique_ptr<ReceiveStatistics> receive_statistics_;
101   std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_;
102   rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
103   rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
104   std::unique_ptr<TaskQueueFactory> task_queue_factory_;
105   std::unique_ptr<AudioIngress> ingress_;
106   std::unique_ptr<AudioEgress> egress_;
107 };
108 
TEST_F(AudioIngressTest,PlayingAfterStartAndStop)109 TEST_F(AudioIngressTest, PlayingAfterStartAndStop) {
110   EXPECT_EQ(ingress_->IsPlaying(), true);
111   ingress_->StopPlay();
112   EXPECT_EQ(ingress_->IsPlaying(), false);
113 }
114 
TEST_F(AudioIngressTest,GetAudioFrameAfterRtpReceived)115 TEST_F(AudioIngressTest, GetAudioFrameAfterRtpReceived) {
116   rtc::Event event;
117   auto handle_rtp = [&](const uint8_t* packet, size_t length, Unused) {
118     ingress_->ReceivedRTPPacket(rtc::ArrayView<const uint8_t>(packet, length));
119     event.Set();
120     return true;
121   };
122   EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(handle_rtp));
123   egress_->SendAudioData(GetAudioFrame(0));
124   egress_->SendAudioData(GetAudioFrame(1));
125   event.Wait(TimeDelta::Seconds(1));
126 
127   AudioFrame audio_frame;
128   EXPECT_EQ(
129       ingress_->GetAudioFrameWithInfo(kPcmuFormat.clockrate_hz, &audio_frame),
130       AudioMixer::Source::AudioFrameInfo::kNormal);
131   EXPECT_FALSE(audio_frame.muted());
132   EXPECT_EQ(audio_frame.num_channels_, 1u);
133   EXPECT_EQ(audio_frame.samples_per_channel_,
134             static_cast<size_t>(kPcmuFormat.clockrate_hz / 100));
135   EXPECT_EQ(audio_frame.sample_rate_hz_, kPcmuFormat.clockrate_hz);
136   EXPECT_NE(audio_frame.timestamp_, 0u);
137   EXPECT_EQ(audio_frame.elapsed_time_ms_, 0);
138 }
139 
TEST_F(AudioIngressTest,TestSpeechOutputLevelAndEnergyDuration)140 TEST_F(AudioIngressTest, TestSpeechOutputLevelAndEnergyDuration) {
141   // Per audio_level's kUpdateFrequency, we need more than 10 audio samples to
142   // get audio level from output source.
143   constexpr int kNumRtp = 6;
144   int rtp_count = 0;
145   rtc::Event event;
146   auto handle_rtp = [&](const uint8_t* packet, size_t length, Unused) {
147     ingress_->ReceivedRTPPacket(rtc::ArrayView<const uint8_t>(packet, length));
148     if (++rtp_count == kNumRtp) {
149       event.Set();
150     }
151     return true;
152   };
153   EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(handle_rtp));
154   for (int i = 0; i < kNumRtp * 2; i++) {
155     egress_->SendAudioData(GetAudioFrame(i));
156     fake_clock_.AdvanceTimeMilliseconds(10);
157   }
158   event.Wait(/*give_up_after=*/TimeDelta::Seconds(1));
159 
160   for (int i = 0; i < kNumRtp * 2; ++i) {
161     AudioFrame audio_frame;
162     EXPECT_EQ(
163         ingress_->GetAudioFrameWithInfo(kPcmuFormat.clockrate_hz, &audio_frame),
164         AudioMixer::Source::AudioFrameInfo::kNormal);
165   }
166   EXPECT_EQ(ingress_->GetOutputAudioLevel(), kAudioLevel);
167 
168   constexpr double kExpectedEnergy = 0.00016809565587789564;
169   constexpr double kExpectedDuration = 0.11999999999999998;
170 
171   EXPECT_DOUBLE_EQ(ingress_->GetOutputTotalEnergy(), kExpectedEnergy);
172   EXPECT_DOUBLE_EQ(ingress_->GetOutputTotalDuration(), kExpectedDuration);
173 }
174 
TEST_F(AudioIngressTest,PreferredSampleRate)175 TEST_F(AudioIngressTest, PreferredSampleRate) {
176   rtc::Event event;
177   auto handle_rtp = [&](const uint8_t* packet, size_t length, Unused) {
178     ingress_->ReceivedRTPPacket(rtc::ArrayView<const uint8_t>(packet, length));
179     event.Set();
180     return true;
181   };
182   EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(handle_rtp));
183   egress_->SendAudioData(GetAudioFrame(0));
184   egress_->SendAudioData(GetAudioFrame(1));
185   event.Wait(TimeDelta::Seconds(1));
186 
187   AudioFrame audio_frame;
188   EXPECT_EQ(
189       ingress_->GetAudioFrameWithInfo(kPcmuFormat.clockrate_hz, &audio_frame),
190       AudioMixer::Source::AudioFrameInfo::kNormal);
191   EXPECT_EQ(ingress_->PreferredSampleRate(), kPcmuFormat.clockrate_hz);
192 }
193 
194 // This test highlights the case where caller invokes StopPlay() which then
195 // AudioIngress should play silence frame afterwards.
TEST_F(AudioIngressTest,GetMutedAudioFrameAfterRtpReceivedAndStopPlay)196 TEST_F(AudioIngressTest, GetMutedAudioFrameAfterRtpReceivedAndStopPlay) {
197   // StopPlay before we start sending RTP packet with sine wave.
198   ingress_->StopPlay();
199 
200   // Send 6 RTP packets to generate more than 100 ms audio sample to get
201   // valid speech level.
202   constexpr int kNumRtp = 6;
203   int rtp_count = 0;
204   rtc::Event event;
205   auto handle_rtp = [&](const uint8_t* packet, size_t length, Unused) {
206     ingress_->ReceivedRTPPacket(rtc::ArrayView<const uint8_t>(packet, length));
207     if (++rtp_count == kNumRtp) {
208       event.Set();
209     }
210     return true;
211   };
212   EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(handle_rtp));
213   for (int i = 0; i < kNumRtp * 2; i++) {
214     egress_->SendAudioData(GetAudioFrame(i));
215     fake_clock_.AdvanceTimeMilliseconds(10);
216   }
217   event.Wait(/*give_up_after=*/TimeDelta::Seconds(1));
218 
219   for (int i = 0; i < kNumRtp * 2; ++i) {
220     AudioFrame audio_frame;
221     EXPECT_EQ(
222         ingress_->GetAudioFrameWithInfo(kPcmuFormat.clockrate_hz, &audio_frame),
223         AudioMixer::Source::AudioFrameInfo::kMuted);
224     const int16_t* audio_data = audio_frame.data();
225     size_t length =
226         audio_frame.samples_per_channel_ * audio_frame.num_channels_;
227     for (size_t j = 0; j < length; ++j) {
228       EXPECT_EQ(audio_data[j], 0);
229     }
230   }
231 
232   // Now we should still see valid speech output level as StopPlay won't affect
233   // the measurement.
234   EXPECT_EQ(ingress_->GetOutputAudioLevel(), kAudioLevel);
235 }
236 
237 }  // namespace
238 }  // namespace webrtc
239