xref: /aosp_15_r20/external/webrtc/modules/audio_coding/test/TwoWayCommunication.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2012 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 "TwoWayCommunication.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <stdio.h>
14*d9f75844SAndroid Build Coastguard Worker #include <string.h>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include <memory>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
20*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_coding/test/PCMFile.h"
21*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
22*d9f75844SAndroid Build Coastguard Worker #include "test/testsupport/file_utils.h"
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker #define MAX_FILE_NAME_LENGTH_BYTE 500
27*d9f75844SAndroid Build Coastguard Worker 
TwoWayCommunication()28*d9f75844SAndroid Build Coastguard Worker TwoWayCommunication::TwoWayCommunication()
29*d9f75844SAndroid Build Coastguard Worker     : _acmA(AudioCodingModule::Create(
30*d9f75844SAndroid Build Coastguard Worker           AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
31*d9f75844SAndroid Build Coastguard Worker       _acmRefA(AudioCodingModule::Create(
32*d9f75844SAndroid Build Coastguard Worker           AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {
33*d9f75844SAndroid Build Coastguard Worker   AudioCodingModule::Config config;
34*d9f75844SAndroid Build Coastguard Worker   // The clicks will be more obvious if time-stretching is not allowed.
35*d9f75844SAndroid Build Coastguard Worker   // TODO(henrik.lundin) Really?
36*d9f75844SAndroid Build Coastguard Worker   config.neteq_config.for_test_no_time_stretching = true;
37*d9f75844SAndroid Build Coastguard Worker   config.decoder_factory = CreateBuiltinAudioDecoderFactory();
38*d9f75844SAndroid Build Coastguard Worker   _acmB.reset(AudioCodingModule::Create(config));
39*d9f75844SAndroid Build Coastguard Worker   _acmRefB.reset(AudioCodingModule::Create(config));
40*d9f75844SAndroid Build Coastguard Worker }
41*d9f75844SAndroid Build Coastguard Worker 
~TwoWayCommunication()42*d9f75844SAndroid Build Coastguard Worker TwoWayCommunication::~TwoWayCommunication() {
43*d9f75844SAndroid Build Coastguard Worker   delete _channel_A2B;
44*d9f75844SAndroid Build Coastguard Worker   delete _channel_B2A;
45*d9f75844SAndroid Build Coastguard Worker   delete _channelRef_A2B;
46*d9f75844SAndroid Build Coastguard Worker   delete _channelRef_B2A;
47*d9f75844SAndroid Build Coastguard Worker   _inFileA.Close();
48*d9f75844SAndroid Build Coastguard Worker   _inFileB.Close();
49*d9f75844SAndroid Build Coastguard Worker   _outFileA.Close();
50*d9f75844SAndroid Build Coastguard Worker   _outFileB.Close();
51*d9f75844SAndroid Build Coastguard Worker   _outFileRefA.Close();
52*d9f75844SAndroid Build Coastguard Worker   _outFileRefB.Close();
53*d9f75844SAndroid Build Coastguard Worker }
54*d9f75844SAndroid Build Coastguard Worker 
SetUpAutotest(AudioEncoderFactory * const encoder_factory,const SdpAudioFormat & format1,const int payload_type1,const SdpAudioFormat & format2,const int payload_type2)55*d9f75844SAndroid Build Coastguard Worker void TwoWayCommunication::SetUpAutotest(
56*d9f75844SAndroid Build Coastguard Worker     AudioEncoderFactory* const encoder_factory,
57*d9f75844SAndroid Build Coastguard Worker     const SdpAudioFormat& format1,
58*d9f75844SAndroid Build Coastguard Worker     const int payload_type1,
59*d9f75844SAndroid Build Coastguard Worker     const SdpAudioFormat& format2,
60*d9f75844SAndroid Build Coastguard Worker     const int payload_type2) {
61*d9f75844SAndroid Build Coastguard Worker   //--- Set A codecs
62*d9f75844SAndroid Build Coastguard Worker   _acmA->SetEncoder(
63*d9f75844SAndroid Build Coastguard Worker       encoder_factory->MakeAudioEncoder(payload_type1, format1, absl::nullopt));
64*d9f75844SAndroid Build Coastguard Worker   _acmA->SetReceiveCodecs({{payload_type2, format2}});
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker   //--- Set ref-A codecs
67*d9f75844SAndroid Build Coastguard Worker   _acmRefA->SetEncoder(
68*d9f75844SAndroid Build Coastguard Worker       encoder_factory->MakeAudioEncoder(payload_type1, format1, absl::nullopt));
69*d9f75844SAndroid Build Coastguard Worker   _acmRefA->SetReceiveCodecs({{payload_type2, format2}});
70*d9f75844SAndroid Build Coastguard Worker 
71*d9f75844SAndroid Build Coastguard Worker   //--- Set B codecs
72*d9f75844SAndroid Build Coastguard Worker   _acmB->SetEncoder(
73*d9f75844SAndroid Build Coastguard Worker       encoder_factory->MakeAudioEncoder(payload_type2, format2, absl::nullopt));
74*d9f75844SAndroid Build Coastguard Worker   _acmB->SetReceiveCodecs({{payload_type1, format1}});
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker   //--- Set ref-B codecs
77*d9f75844SAndroid Build Coastguard Worker   _acmRefB->SetEncoder(
78*d9f75844SAndroid Build Coastguard Worker       encoder_factory->MakeAudioEncoder(payload_type2, format2, absl::nullopt));
79*d9f75844SAndroid Build Coastguard Worker   _acmRefB->SetReceiveCodecs({{payload_type1, format1}});
80*d9f75844SAndroid Build Coastguard Worker 
81*d9f75844SAndroid Build Coastguard Worker   uint16_t frequencyHz;
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   //--- Input A and B
84*d9f75844SAndroid Build Coastguard Worker   std::string in_file_name =
85*d9f75844SAndroid Build Coastguard Worker       webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
86*d9f75844SAndroid Build Coastguard Worker   frequencyHz = 16000;
87*d9f75844SAndroid Build Coastguard Worker   _inFileA.Open(in_file_name, frequencyHz, "rb");
88*d9f75844SAndroid Build Coastguard Worker   _inFileB.Open(in_file_name, frequencyHz, "rb");
89*d9f75844SAndroid Build Coastguard Worker 
90*d9f75844SAndroid Build Coastguard Worker   //--- Output A
91*d9f75844SAndroid Build Coastguard Worker   std::string output_file_a = webrtc::test::OutputPath() + "outAutotestA.pcm";
92*d9f75844SAndroid Build Coastguard Worker   frequencyHz = 16000;
93*d9f75844SAndroid Build Coastguard Worker   _outFileA.Open(output_file_a, frequencyHz, "wb");
94*d9f75844SAndroid Build Coastguard Worker   std::string output_ref_file_a =
95*d9f75844SAndroid Build Coastguard Worker       webrtc::test::OutputPath() + "ref_outAutotestA.pcm";
96*d9f75844SAndroid Build Coastguard Worker   _outFileRefA.Open(output_ref_file_a, frequencyHz, "wb");
97*d9f75844SAndroid Build Coastguard Worker 
98*d9f75844SAndroid Build Coastguard Worker   //--- Output B
99*d9f75844SAndroid Build Coastguard Worker   std::string output_file_b = webrtc::test::OutputPath() + "outAutotestB.pcm";
100*d9f75844SAndroid Build Coastguard Worker   frequencyHz = 16000;
101*d9f75844SAndroid Build Coastguard Worker   _outFileB.Open(output_file_b, frequencyHz, "wb");
102*d9f75844SAndroid Build Coastguard Worker   std::string output_ref_file_b =
103*d9f75844SAndroid Build Coastguard Worker       webrtc::test::OutputPath() + "ref_outAutotestB.pcm";
104*d9f75844SAndroid Build Coastguard Worker   _outFileRefB.Open(output_ref_file_b, frequencyHz, "wb");
105*d9f75844SAndroid Build Coastguard Worker 
106*d9f75844SAndroid Build Coastguard Worker   //--- Set A-to-B channel
107*d9f75844SAndroid Build Coastguard Worker   _channel_A2B = new Channel;
108*d9f75844SAndroid Build Coastguard Worker   _acmA->RegisterTransportCallback(_channel_A2B);
109*d9f75844SAndroid Build Coastguard Worker   _channel_A2B->RegisterReceiverACM(_acmB.get());
110*d9f75844SAndroid Build Coastguard Worker   //--- Do the same for the reference
111*d9f75844SAndroid Build Coastguard Worker   _channelRef_A2B = new Channel;
112*d9f75844SAndroid Build Coastguard Worker   _acmRefA->RegisterTransportCallback(_channelRef_A2B);
113*d9f75844SAndroid Build Coastguard Worker   _channelRef_A2B->RegisterReceiverACM(_acmRefB.get());
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker   //--- Set B-to-A channel
116*d9f75844SAndroid Build Coastguard Worker   _channel_B2A = new Channel;
117*d9f75844SAndroid Build Coastguard Worker   _acmB->RegisterTransportCallback(_channel_B2A);
118*d9f75844SAndroid Build Coastguard Worker   _channel_B2A->RegisterReceiverACM(_acmA.get());
119*d9f75844SAndroid Build Coastguard Worker   //--- Do the same for reference
120*d9f75844SAndroid Build Coastguard Worker   _channelRef_B2A = new Channel;
121*d9f75844SAndroid Build Coastguard Worker   _acmRefB->RegisterTransportCallback(_channelRef_B2A);
122*d9f75844SAndroid Build Coastguard Worker   _channelRef_B2A->RegisterReceiverACM(_acmRefA.get());
123*d9f75844SAndroid Build Coastguard Worker }
124*d9f75844SAndroid Build Coastguard Worker 
Perform()125*d9f75844SAndroid Build Coastguard Worker void TwoWayCommunication::Perform() {
126*d9f75844SAndroid Build Coastguard Worker   const SdpAudioFormat format1("ISAC", 16000, 1);
127*d9f75844SAndroid Build Coastguard Worker   const SdpAudioFormat format2("L16", 8000, 1);
128*d9f75844SAndroid Build Coastguard Worker   constexpr int payload_type1 = 17, payload_type2 = 18;
129*d9f75844SAndroid Build Coastguard Worker 
130*d9f75844SAndroid Build Coastguard Worker   auto encoder_factory = CreateBuiltinAudioEncoderFactory();
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker   SetUpAutotest(encoder_factory.get(), format1, payload_type1, format2,
133*d9f75844SAndroid Build Coastguard Worker                 payload_type2);
134*d9f75844SAndroid Build Coastguard Worker 
135*d9f75844SAndroid Build Coastguard Worker   unsigned int msecPassed = 0;
136*d9f75844SAndroid Build Coastguard Worker   unsigned int secPassed = 0;
137*d9f75844SAndroid Build Coastguard Worker 
138*d9f75844SAndroid Build Coastguard Worker   int32_t outFreqHzA = _outFileA.SamplingFrequency();
139*d9f75844SAndroid Build Coastguard Worker   int32_t outFreqHzB = _outFileB.SamplingFrequency();
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   AudioFrame audioFrame;
142*d9f75844SAndroid Build Coastguard Worker 
143*d9f75844SAndroid Build Coastguard Worker   // In the following loop we tests that the code can handle misuse of the APIs.
144*d9f75844SAndroid Build Coastguard Worker   // In the middle of a session with data flowing between two sides, called A
145*d9f75844SAndroid Build Coastguard Worker   // and B, APIs will be called, and the code should continue to run, and be
146*d9f75844SAndroid Build Coastguard Worker   // able to recover.
147*d9f75844SAndroid Build Coastguard Worker   while (!_inFileA.EndOfFile() && !_inFileB.EndOfFile()) {
148*d9f75844SAndroid Build Coastguard Worker     msecPassed += 10;
149*d9f75844SAndroid Build Coastguard Worker     EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
150*d9f75844SAndroid Build Coastguard Worker     EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
151*d9f75844SAndroid Build Coastguard Worker     EXPECT_GE(_acmRefA->Add10MsData(audioFrame), 0);
152*d9f75844SAndroid Build Coastguard Worker 
153*d9f75844SAndroid Build Coastguard Worker     EXPECT_GT(_inFileB.Read10MsData(audioFrame), 0);
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker     EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
156*d9f75844SAndroid Build Coastguard Worker     EXPECT_GE(_acmRefB->Add10MsData(audioFrame), 0);
157*d9f75844SAndroid Build Coastguard Worker     bool muted;
158*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, _acmA->PlayoutData10Ms(outFreqHzA, &audioFrame, &muted));
159*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(muted);
160*d9f75844SAndroid Build Coastguard Worker     _outFileA.Write10MsData(audioFrame);
161*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, _acmRefA->PlayoutData10Ms(outFreqHzA, &audioFrame, &muted));
162*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(muted);
163*d9f75844SAndroid Build Coastguard Worker     _outFileRefA.Write10MsData(audioFrame);
164*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
165*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(muted);
166*d9f75844SAndroid Build Coastguard Worker     _outFileB.Write10MsData(audioFrame);
167*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, _acmRefB->PlayoutData10Ms(outFreqHzB, &audioFrame, &muted));
168*d9f75844SAndroid Build Coastguard Worker     ASSERT_FALSE(muted);
169*d9f75844SAndroid Build Coastguard Worker     _outFileRefB.Write10MsData(audioFrame);
170*d9f75844SAndroid Build Coastguard Worker 
171*d9f75844SAndroid Build Coastguard Worker     // Update time counters each time a second of data has passed.
172*d9f75844SAndroid Build Coastguard Worker     if (msecPassed >= 1000) {
173*d9f75844SAndroid Build Coastguard Worker       msecPassed = 0;
174*d9f75844SAndroid Build Coastguard Worker       secPassed++;
175*d9f75844SAndroid Build Coastguard Worker     }
176*d9f75844SAndroid Build Coastguard Worker     // Re-register send codec on side B.
177*d9f75844SAndroid Build Coastguard Worker     if (((secPassed % 5) == 4) && (msecPassed >= 990)) {
178*d9f75844SAndroid Build Coastguard Worker       _acmB->SetEncoder(encoder_factory->MakeAudioEncoder(
179*d9f75844SAndroid Build Coastguard Worker           payload_type2, format2, absl::nullopt));
180*d9f75844SAndroid Build Coastguard Worker     }
181*d9f75844SAndroid Build Coastguard Worker     // Initialize receiver on side A.
182*d9f75844SAndroid Build Coastguard Worker     if (((secPassed % 7) == 6) && (msecPassed == 0))
183*d9f75844SAndroid Build Coastguard Worker       EXPECT_EQ(0, _acmA->InitializeReceiver());
184*d9f75844SAndroid Build Coastguard Worker     // Re-register codec on side A.
185*d9f75844SAndroid Build Coastguard Worker     if (((secPassed % 7) == 6) && (msecPassed >= 990)) {
186*d9f75844SAndroid Build Coastguard Worker       _acmA->SetReceiveCodecs({{payload_type2, format2}});
187*d9f75844SAndroid Build Coastguard Worker     }
188*d9f75844SAndroid Build Coastguard Worker   }
189*d9f75844SAndroid Build Coastguard Worker }
190*d9f75844SAndroid Build Coastguard Worker 
191*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
192