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