2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webrtc/common_types.h"
19 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
20 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
21 #include "webrtc/modules/audio_coding/main/test/utility.h"
22 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
23 #include "webrtc/system_wrappers/interface/trace.h"
24 #include "webrtc/test/testsupport/fileutils.h"
28 TestPacketization::TestPacketization(RTPStream *rtpStream, uint16_t frequency)
29 : _rtpStream(rtpStream),
30 _frequency(frequency),
34 TestPacketization::~TestPacketization() {
37 int32_t TestPacketization::SendData(
38 const FrameType /* frameType */, const uint8_t payloadType,
39 const uint32_t timeStamp, const uint8_t* payloadData,
40 const uint16_t payloadSize,
41 const RTPFragmentationHeader* /* fragmentation */) {
42 _rtpStream->Write(payloadType, timeStamp, _seqNo++, payloadData, payloadSize,
51 _packetization(NULL) {
54 void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream,
55 std::string in_file_name, int sample_rate, int channels) {
56 acm->InitializeSender();
57 struct CodecInst sendCodec;
58 int noOfCodecs = acm->NumberOfCodecs();
62 const std::string file_name = webrtc::test::ResourcePath(in_file_name, "pcm");
63 _pcmFile.Open(file_name, sample_rate, "rb");
65 _pcmFile.ReadStereo(true);
68 // Set the codec for the current test.
69 if ((testMode == 0) || (testMode == 1)) {
73 // Choose codec on command line.
74 printf("List of supported codec.\n");
75 for (int n = 0; n < noOfCodecs; n++) {
76 EXPECT_EQ(0, acm->Codec(n, &sendCodec));
77 printf("%d %s\n", n, sendCodec.plname);
79 printf("Choose your codec:");
80 ASSERT_GT(scanf("%d", &codecNo), 0);
83 EXPECT_EQ(0, acm->Codec(codecNo, &sendCodec));
85 sendCodec.channels = channels;
87 EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
88 _packetization = new TestPacketization(rtpStream, sendCodec.plfreq);
89 EXPECT_EQ(0, acm->RegisterTransportCallback(_packetization));
94 void Sender::Teardown() {
96 delete _packetization;
99 bool Sender::Add10MsData() {
100 if (!_pcmFile.EndOfFile()) {
101 EXPECT_GT(_pcmFile.Read10MsData(_audioFrame), 0);
102 int32_t ok = _acm->Add10MsData(_audioFrame);
114 if (!Add10MsData()) {
117 EXPECT_GT(_acm->Process(), -1);
122 : _playoutLengthSmpls(WEBRTC_10MS_PCM_AUDIO),
123 _payloadSizeBytes(MAX_INCOMING_PAYLOAD) {
126 void Receiver::Setup(AudioCodingModule *acm, RTPStream *rtpStream,
127 std::string out_file_name, int channels) {
128 struct CodecInst recvCodec = CodecInst();
130 EXPECT_EQ(0, acm->InitializeReceiver());
132 noOfCodecs = acm->NumberOfCodecs();
133 for (int i = 0; i < noOfCodecs; i++) {
134 EXPECT_EQ(0, acm->Codec(i, &recvCodec));
135 if (recvCodec.channels == channels)
136 EXPECT_EQ(0, acm->RegisterReceiveCodec(recvCodec));
137 // Forces mono/stereo for Opus.
138 if (!strcmp(recvCodec.plname, "opus")) {
139 recvCodec.channels = channels;
140 EXPECT_EQ(0, acm->RegisterReceiveCodec(recvCodec));
145 std::string file_name;
146 std::stringstream file_stream;
147 file_stream << webrtc::test::OutputPath() << out_file_name
148 << static_cast<int>(codeId) << ".pcm";
149 file_name = file_stream.str();
150 _rtpStream = rtpStream;
153 playSampFreq = recvCodec.plfreq;
154 _pcmFile.Open(file_name, recvCodec.plfreq, "wb+");
155 } else if (testMode == 0) {
156 playSampFreq = 32000;
157 _pcmFile.Open(file_name, 32000, "wb+");
159 printf("\nValid output frequencies:\n");
160 printf("8000\n16000\n32000\n-1,");
161 printf("which means output frequency equal to received signal frequency");
162 printf("\n\nChoose output sampling frequency: ");
163 ASSERT_GT(scanf("%d", &playSampFreq), 0);
164 file_name = webrtc::test::OutputPath() + out_file_name + ".pcm";
165 _pcmFile.Open(file_name, playSampFreq, "wb+");
168 _realPayloadSizeBytes = 0;
169 _playoutBuffer = new int16_t[WEBRTC_10MS_PCM_AUDIO];
170 _frequency = playSampFreq;
175 void Receiver::Teardown() {
176 delete[] _playoutBuffer;
179 Trace::ReturnTrace();
183 bool Receiver::IncomingPacket() {
184 if (!_rtpStream->EndOfFile()) {
187 _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload,
188 _payloadSizeBytes, &_nextTime);
189 if (_realPayloadSizeBytes == 0) {
190 if (_rtpStream->EndOfFile()) {
199 EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes,
201 _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload,
202 _payloadSizeBytes, &_nextTime);
203 if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
210 bool Receiver::PlayoutData() {
211 AudioFrame audioFrame;
213 int32_t ok =_acm->PlayoutData10Ms(_frequency, &audioFrame);
218 if (_playoutLengthSmpls == 0) {
221 _pcmFile.Write10MsData(audioFrame.data_,
222 audioFrame.samples_per_channel_ * audioFrame.num_channels_);
226 void Receiver::Run() {
227 uint8_t counter500Ms = 50;
230 while (counter500Ms > 0) {
231 if (clock == 0 || clock >= _nextTime) {
232 EXPECT_TRUE(IncomingPacket());
237 if ((clock % 10) == 0) {
238 if (!PlayoutData()) {
243 if (_rtpStream->EndOfFile()) {
250 EncodeDecodeTest::EncodeDecodeTest() {
252 Trace::CreateTrace();
254 (webrtc::test::OutputPath() + "acm_encdec_trace.txt").c_str());
257 EncodeDecodeTest::EncodeDecodeTest(int testMode) {
258 //testMode == 0 for autotest
259 //testMode == 1 for testing all codecs/parameters
260 //testMode > 1 for specific user-input test (as it was used before)
261 _testMode = testMode;
262 if (_testMode != 0) {
263 Trace::CreateTrace();
265 (webrtc::test::OutputPath() + "acm_encdec_trace.txt").c_str());
269 void EncodeDecodeTest::Perform() {
271 int codePars[3]; // Frequency, packet size, rate.
272 int numPars[52]; // Number of codec parameters sets (freq, pacsize, rate)
273 // to test, for a given codec.
279 scoped_ptr<AudioCodingModule> acm(AudioCodingModule::Create(0));
280 struct CodecInst sendCodecTmp;
281 numCodecs = acm->NumberOfCodecs();
283 if (_testMode != 2) {
284 for (int n = 0; n < numCodecs; n++) {
285 EXPECT_EQ(0, acm->Codec(n, &sendCodecTmp));
286 if (STR_CASE_CMP(sendCodecTmp.plname, "telephone-event") == 0) {
288 } else if (STR_CASE_CMP(sendCodecTmp.plname, "cn") == 0) {
290 } else if (STR_CASE_CMP(sendCodecTmp.plname, "red") == 0) {
292 } else if (sendCodecTmp.channels == 2) {
303 _receiver.testMode = _testMode;
305 // Loop over all mono codecs:
306 for (int codeId = 0; codeId < numCodecs; codeId++) {
307 // Only encode using real mono encoders, not telephone-event and cng.
308 for (int loopPars = 1; loopPars <= numPars[codeId]; loopPars++) {
309 // Encode all data to file.
310 EncodeToFile(1, codeId, codePars, _testMode);
313 std::string fileName = webrtc::test::OutputPath() + "outFile.rtp";
314 rtpFile.Open(fileName.c_str(), "rb");
316 _receiver.codeId = codeId;
318 rtpFile.ReadHeader();
319 _receiver.Setup(acm.get(), &rtpFile, "encodeDecode_out", 1);
321 _receiver.Teardown();
327 if (_testMode == 1) {
328 Trace::ReturnTrace();
332 void EncodeDecodeTest::EncodeToFile(int fileType, int codeId, int* codePars,
334 scoped_ptr<AudioCodingModule> acm(AudioCodingModule::Create(1));
336 std::string fileName = webrtc::test::OutputPath() + "outFile.rtp";
337 rtpFile.Open(fileName.c_str(), "wb+");
338 rtpFile.WriteHeader();
340 // Store for auto_test and logging.
341 _sender.testMode = testMode;
342 _sender.codeId = codeId;
344 _sender.Setup(acm.get(), &rtpFile, "audio_coding/testfile32kHz", 32000, 1);
345 struct CodecInst sendCodecInst;
346 if (acm->SendCodec(&sendCodecInst) >= 0) {
353 } // namespace webrtc