| /* |
| * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "modules/audio_coding/acm2/acm_receive_test.h" |
| |
| #include <stdio.h> |
| |
| #include <memory> |
| |
| #include "api/audio_codecs/builtin_audio_decoder_factory.h" |
| #include "modules/audio_coding/include/audio_coding_module.h" |
| #include "modules/audio_coding/neteq/tools/audio_sink.h" |
| #include "modules/audio_coding/neteq/tools/packet.h" |
| #include "modules/audio_coding/neteq/tools/packet_source.h" |
| #include "test/gtest.h" |
| |
| namespace webrtc { |
| namespace test { |
| |
| namespace { |
| acm2::AcmReceiver::Config MakeAcmConfig( |
| Clock& clock, |
| rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) { |
| acm2::AcmReceiver::Config config; |
| config.clock = clock; |
| config.decoder_factory = std::move(decoder_factory); |
| return config; |
| } |
| } // namespace |
| |
| AcmReceiveTestOldApi::AcmReceiveTestOldApi( |
| PacketSource* packet_source, |
| AudioSink* audio_sink, |
| int output_freq_hz, |
| NumOutputChannels exptected_output_channels, |
| rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) |
| : clock_(0), |
| acm_receiver_(std::make_unique<acm2::AcmReceiver>( |
| MakeAcmConfig(clock_, std::move(decoder_factory)))), |
| packet_source_(packet_source), |
| audio_sink_(audio_sink), |
| output_freq_hz_(output_freq_hz), |
| exptected_output_channels_(exptected_output_channels) {} |
| |
| AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default; |
| |
| void AcmReceiveTestOldApi::RegisterDefaultCodecs() { |
| acm_receiver_->SetCodecs({{103, {"ISAC", 16000, 1}}, |
| {104, {"ISAC", 32000, 1}}, |
| {107, {"L16", 8000, 1}}, |
| {108, {"L16", 16000, 1}}, |
| {109, {"L16", 32000, 1}}, |
| {111, {"L16", 8000, 2}}, |
| {112, {"L16", 16000, 2}}, |
| {113, {"L16", 32000, 2}}, |
| {0, {"PCMU", 8000, 1}}, |
| {110, {"PCMU", 8000, 2}}, |
| {8, {"PCMA", 8000, 1}}, |
| {118, {"PCMA", 8000, 2}}, |
| {102, {"ILBC", 8000, 1}}, |
| {9, {"G722", 8000, 1}}, |
| {119, {"G722", 8000, 2}}, |
| {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}, |
| {13, {"CN", 8000, 1}}, |
| {98, {"CN", 16000, 1}}, |
| {99, {"CN", 32000, 1}}}); |
| } |
| |
| // Remaps payload types from ACM's default to those used in the resource file |
| // neteq_universal_new.rtp. |
| void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() { |
| acm_receiver_->SetCodecs({{103, {"ISAC", 16000, 1}}, |
| {104, {"ISAC", 32000, 1}}, |
| {93, {"L16", 8000, 1}}, |
| {94, {"L16", 16000, 1}}, |
| {95, {"L16", 32000, 1}}, |
| {0, {"PCMU", 8000, 1}}, |
| {8, {"PCMA", 8000, 1}}, |
| {102, {"ILBC", 8000, 1}}, |
| {9, {"G722", 8000, 1}}, |
| {120, {"OPUS", 48000, 2}}, |
| {13, {"CN", 8000, 1}}, |
| {98, {"CN", 16000, 1}}, |
| {99, {"CN", 32000, 1}}}); |
| } |
| |
| void AcmReceiveTestOldApi::Run() { |
| for (std::unique_ptr<Packet> packet(packet_source_->NextPacket()); packet; |
| packet = packet_source_->NextPacket()) { |
| // Pull audio until time to insert packet. |
| while (clock_.TimeInMilliseconds() < packet->time_ms()) { |
| AudioFrame output_frame; |
| bool muted; |
| EXPECT_EQ( |
| 0, acm_receiver_->GetAudio(output_freq_hz_, &output_frame, &muted)); |
| ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_); |
| ASSERT_FALSE(muted); |
| const size_t samples_per_block = |
| static_cast<size_t>(output_freq_hz_ * 10 / 1000); |
| EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_); |
| if (exptected_output_channels_ != kArbitraryChannels) { |
| if (output_frame.speech_type_ == webrtc::AudioFrame::kPLC) { |
| // Don't check number of channels for PLC output, since each test run |
| // usually starts with a short period of mono PLC before decoding the |
| // first packet. |
| } else { |
| EXPECT_EQ(exptected_output_channels_, output_frame.num_channels_); |
| } |
| } |
| ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame)); |
| clock_.AdvanceTimeMilliseconds(10); |
| AfterGetAudio(); |
| } |
| |
| EXPECT_EQ(0, acm_receiver_->InsertPacket( |
| packet->header(), |
| rtc::ArrayView<const uint8_t>( |
| packet->payload(), packet->payload_length_bytes()))) |
| << "Failure when inserting packet:" << std::endl |
| << " PT = " << static_cast<int>(packet->header().payloadType) |
| << std::endl |
| << " TS = " << packet->header().timestamp << std::endl |
| << " SN = " << packet->header().sequenceNumber; |
| } |
| } |
| |
| AcmReceiveTestToggleOutputFreqOldApi::AcmReceiveTestToggleOutputFreqOldApi( |
| PacketSource* packet_source, |
| AudioSink* audio_sink, |
| int output_freq_hz_1, |
| int output_freq_hz_2, |
| int toggle_period_ms, |
| NumOutputChannels exptected_output_channels) |
| : AcmReceiveTestOldApi(packet_source, |
| audio_sink, |
| output_freq_hz_1, |
| exptected_output_channels, |
| CreateBuiltinAudioDecoderFactory()), |
| output_freq_hz_1_(output_freq_hz_1), |
| output_freq_hz_2_(output_freq_hz_2), |
| toggle_period_ms_(toggle_period_ms), |
| last_toggle_time_ms_(clock_.TimeInMilliseconds()) {} |
| |
| void AcmReceiveTestToggleOutputFreqOldApi::AfterGetAudio() { |
| if (clock_.TimeInMilliseconds() >= last_toggle_time_ms_ + toggle_period_ms_) { |
| output_freq_hz_ = (output_freq_hz_ == output_freq_hz_1_) |
| ? output_freq_hz_2_ |
| : output_freq_hz_1_; |
| last_toggle_time_ms_ = clock_.TimeInMilliseconds(); |
| } |
| } |
| |
| } // namespace test |
| } // namespace webrtc |