1 /*
2  *  Copyright (c) 2014 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 "modules/audio_coding/acm2/acm_receive_test.h"
12 
13 #include <stdio.h>
14 
15 #include <memory>
16 
17 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
18 #include "modules/audio_coding/include/audio_coding_module.h"
19 #include "modules/audio_coding/neteq/tools/audio_sink.h"
20 #include "modules/audio_coding/neteq/tools/packet.h"
21 #include "modules/audio_coding/neteq/tools/packet_source.h"
22 #include "test/gtest.h"
23 
24 namespace webrtc {
25 namespace test {
26 
27 namespace {
MakeAcmConfig(Clock * clock,rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)28 AudioCodingModule::Config MakeAcmConfig(
29     Clock* clock,
30     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory) {
31   AudioCodingModule::Config config;
32   config.clock = clock;
33   config.decoder_factory = std::move(decoder_factory);
34   return config;
35 }
36 }  // namespace
37 
AcmReceiveTestOldApi(PacketSource * packet_source,AudioSink * audio_sink,int output_freq_hz,NumOutputChannels exptected_output_channels,rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)38 AcmReceiveTestOldApi::AcmReceiveTestOldApi(
39     PacketSource* packet_source,
40     AudioSink* audio_sink,
41     int output_freq_hz,
42     NumOutputChannels exptected_output_channels,
43     rtc::scoped_refptr<AudioDecoderFactory> decoder_factory)
44     : clock_(0),
45       acm_(webrtc::AudioCodingModule::Create(
46           MakeAcmConfig(&clock_, std::move(decoder_factory)))),
47       packet_source_(packet_source),
48       audio_sink_(audio_sink),
49       output_freq_hz_(output_freq_hz),
50       exptected_output_channels_(exptected_output_channels) {}
51 
52 AcmReceiveTestOldApi::~AcmReceiveTestOldApi() = default;
53 
RegisterDefaultCodecs()54 void AcmReceiveTestOldApi::RegisterDefaultCodecs() {
55   acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
56                           {104, {"ISAC", 32000, 1}},
57                           {107, {"L16", 8000, 1}},
58                           {108, {"L16", 16000, 1}},
59                           {109, {"L16", 32000, 1}},
60                           {111, {"L16", 8000, 2}},
61                           {112, {"L16", 16000, 2}},
62                           {113, {"L16", 32000, 2}},
63                           {0, {"PCMU", 8000, 1}},
64                           {110, {"PCMU", 8000, 2}},
65                           {8, {"PCMA", 8000, 1}},
66                           {118, {"PCMA", 8000, 2}},
67                           {102, {"ILBC", 8000, 1}},
68                           {9, {"G722", 8000, 1}},
69                           {119, {"G722", 8000, 2}},
70                           {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}},
71                           {13, {"CN", 8000, 1}},
72                           {98, {"CN", 16000, 1}},
73                           {99, {"CN", 32000, 1}}});
74 }
75 
76 // Remaps payload types from ACM's default to those used in the resource file
77 // neteq_universal_new.rtp.
RegisterNetEqTestCodecs()78 void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() {
79   acm_->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
80                           {104, {"ISAC", 32000, 1}},
81                           {93, {"L16", 8000, 1}},
82                           {94, {"L16", 16000, 1}},
83                           {95, {"L16", 32000, 1}},
84                           {0, {"PCMU", 8000, 1}},
85                           {8, {"PCMA", 8000, 1}},
86                           {102, {"ILBC", 8000, 1}},
87                           {9, {"G722", 8000, 1}},
88                           {120, {"OPUS", 48000, 2}},
89                           {13, {"CN", 8000, 1}},
90                           {98, {"CN", 16000, 1}},
91                           {99, {"CN", 32000, 1}}});
92 }
93 
Run()94 void AcmReceiveTestOldApi::Run() {
95   for (std::unique_ptr<Packet> packet(packet_source_->NextPacket()); packet;
96        packet = packet_source_->NextPacket()) {
97     // Pull audio until time to insert packet.
98     while (clock_.TimeInMilliseconds() < packet->time_ms()) {
99       AudioFrame output_frame;
100       bool muted;
101       EXPECT_EQ(0,
102                 acm_->PlayoutData10Ms(output_freq_hz_, &output_frame, &muted));
103       ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
104       ASSERT_FALSE(muted);
105       const size_t samples_per_block =
106           static_cast<size_t>(output_freq_hz_ * 10 / 1000);
107       EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_);
108       if (exptected_output_channels_ != kArbitraryChannels) {
109         if (output_frame.speech_type_ == webrtc::AudioFrame::kPLC) {
110           // Don't check number of channels for PLC output, since each test run
111           // usually starts with a short period of mono PLC before decoding the
112           // first packet.
113         } else {
114           EXPECT_EQ(exptected_output_channels_, output_frame.num_channels_);
115         }
116       }
117       ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame));
118       clock_.AdvanceTimeMilliseconds(10);
119       AfterGetAudio();
120     }
121 
122     EXPECT_EQ(0, acm_->IncomingPacket(
123                      packet->payload(),
124                      static_cast<int32_t>(packet->payload_length_bytes()),
125                      packet->header()))
126         << "Failure when inserting packet:" << std::endl
127         << "  PT = " << static_cast<int>(packet->header().payloadType)
128         << std::endl
129         << "  TS = " << packet->header().timestamp << std::endl
130         << "  SN = " << packet->header().sequenceNumber;
131   }
132 }
133 
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)134 AcmReceiveTestToggleOutputFreqOldApi::AcmReceiveTestToggleOutputFreqOldApi(
135     PacketSource* packet_source,
136     AudioSink* audio_sink,
137     int output_freq_hz_1,
138     int output_freq_hz_2,
139     int toggle_period_ms,
140     NumOutputChannels exptected_output_channels)
141     : AcmReceiveTestOldApi(packet_source,
142                            audio_sink,
143                            output_freq_hz_1,
144                            exptected_output_channels,
145                            CreateBuiltinAudioDecoderFactory()),
146       output_freq_hz_1_(output_freq_hz_1),
147       output_freq_hz_2_(output_freq_hz_2),
148       toggle_period_ms_(toggle_period_ms),
149       last_toggle_time_ms_(clock_.TimeInMilliseconds()) {}
150 
AfterGetAudio()151 void AcmReceiveTestToggleOutputFreqOldApi::AfterGetAudio() {
152   if (clock_.TimeInMilliseconds() >= last_toggle_time_ms_ + toggle_period_ms_) {
153     output_freq_hz_ = (output_freq_hz_ == output_freq_hz_1_)
154                           ? output_freq_hz_2_
155                           : output_freq_hz_1_;
156     last_toggle_time_ms_ = clock_.TimeInMilliseconds();
157   }
158 }
159 
160 }  // namespace test
161 }  // namespace webrtc
162