blob: eb86a4f93838016ec8e23138ce7696bfdee2c082 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
andrew@webrtc.org9dc45da2012-05-23 15:39:01 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000011#include "webrtc/modules/audio_coding/main/test/iSACTest.h"
12
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <ctype.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014#include <stdio.h>
15#include <string.h>
16
17#if _WIN32
18#include <windows.h>
19#elif WEBRTC_LINUX
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000020#include <time.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000021#else
22#include <sys/time.h>
23#include <time.h>
andrew@webrtc.org89df0922013-09-12 01:27:43 +000024#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000025
turaj@webrtc.org532f3dc2013-09-19 00:12:23 +000026#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000027#include "webrtc/modules/audio_coding/main/test/utility.h"
28#include "webrtc/system_wrappers/interface/event_wrapper.h"
29#include "webrtc/system_wrappers/interface/tick_util.h"
30#include "webrtc/system_wrappers/interface/trace.h"
31#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000032
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000033namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000034
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000035void SetISACConfigDefault(ACMTestISACConfig& isacConfig) {
36 isacConfig.currentRateBitPerSec = 0;
37 isacConfig.currentFrameSizeMsec = 0;
38 isacConfig.maxRateBitPerSec = 0;
39 isacConfig.maxPayloadSizeByte = 0;
40 isacConfig.encodingMode = -1;
41 isacConfig.initRateBitPerSec = 0;
42 isacConfig.initFrameSizeInMsec = 0;
43 isacConfig.enforceFrameSize = false;
44 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000045}
46
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000047int16_t SetISAConfig(ACMTestISACConfig& isacConfig, AudioCodingModule* acm,
48 int testMode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000049
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000050 if ((isacConfig.currentRateBitPerSec != 0)
51 || (isacConfig.currentFrameSizeMsec != 0)) {
52 CodecInst sendCodec;
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000053 EXPECT_EQ(0, acm->SendCodec(&sendCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000054 if (isacConfig.currentRateBitPerSec < 0) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000055 // Register iSAC in adaptive (channel-dependent) mode.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000056 sendCodec.rate = -1;
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000057 EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000058 } else {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000059 if (isacConfig.currentRateBitPerSec != 0) {
60 sendCodec.rate = isacConfig.currentRateBitPerSec;
61 }
62 if (isacConfig.currentFrameSizeMsec != 0) {
63 sendCodec.pacsize = isacConfig.currentFrameSizeMsec
64 * (sendCodec.plfreq / 1000);
65 }
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000066 EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +000067 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000068 }
niklase@google.com470e71d2011-07-07 08:21:25 +000069
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000070 if (isacConfig.maxRateBitPerSec > 0) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000071 // Set max rate.
72 EXPECT_EQ(0, acm->SetISACMaxRate(isacConfig.maxRateBitPerSec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000073 }
74 if (isacConfig.maxPayloadSizeByte > 0) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000075 // Set max payload size.
76 EXPECT_EQ(0, acm->SetISACMaxPayloadSize(isacConfig.maxPayloadSizeByte));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000077 }
78 if ((isacConfig.initFrameSizeInMsec != 0)
79 || (isacConfig.initRateBitPerSec != 0)) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +000080 EXPECT_EQ(0, acm->ConfigISACBandwidthEstimator(
81 static_cast<uint8_t>(isacConfig.initFrameSizeInMsec),
82 static_cast<uint16_t>(isacConfig.initRateBitPerSec),
83 isacConfig.enforceFrameSize));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000084 }
niklase@google.com470e71d2011-07-07 08:21:25 +000085
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000086 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000087}
88
turaj@webrtc.org6ea3d1c2013-10-02 21:44:33 +000089ISACTest::ISACTest(int testMode, const Config& config)
90 : _acmA(config.Get<AudioCodingModuleFactory>().Create(1)),
91 _acmB(config.Get<AudioCodingModuleFactory>().Create(2)),
andrew@webrtc.org89df0922013-09-12 01:27:43 +000092 _testMode(testMode) {
niklase@google.com470e71d2011-07-07 08:21:25 +000093}
94
turaj@webrtc.org55e17232013-10-29 04:40:09 +000095ISACTest::~ISACTest() {}
niklase@google.com470e71d2011-07-07 08:21:25 +000096
turaj@webrtc.org7cc64b32014-01-10 22:35:09 +000097void ISACTest::Run10ms() {
98 AudioFrame audioFrame;
99 EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
100 EXPECT_EQ(0, _acmA->Add10MsData(audioFrame));
101 EXPECT_EQ(0, _acmB->Add10MsData(audioFrame));
102 EXPECT_GT(_acmA->Process(), -1);
103 EXPECT_GT(_acmB->Process(), -1);
104 EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame));
105 _outFileA.Write10MsData(audioFrame);
106 EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame));
107 _outFileB.Write10MsData(audioFrame);
108}
109
110
111#if (defined(WEBRTC_CODEC_ISAC))
112// Depending on whether the floating-point iSAC is activated the following
113// implementations would differ.
114
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000115void ISACTest::Setup() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000116 int codecCntr;
117 CodecInst codecParam;
niklase@google.com470e71d2011-07-07 08:21:25 +0000118
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000119 for (codecCntr = 0; codecCntr < AudioCodingModule::NumberOfCodecs();
120 codecCntr++) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000121 EXPECT_EQ(0, AudioCodingModule::Codec(codecCntr, &codecParam));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000122 if (!STR_CASE_CMP(codecParam.plname, "ISAC")
123 && codecParam.plfreq == 16000) {
124 memcpy(&_paramISAC16kHz, &codecParam, sizeof(CodecInst));
125 _idISAC16kHz = codecCntr;
niklase@google.com470e71d2011-07-07 08:21:25 +0000126 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000127 if (!STR_CASE_CMP(codecParam.plname, "ISAC")
128 && codecParam.plfreq == 32000) {
129 memcpy(&_paramISAC32kHz, &codecParam, sizeof(CodecInst));
130 _idISAC32kHz = codecCntr;
niklase@google.com470e71d2011-07-07 08:21:25 +0000131 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000132 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000133
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000134 // Register both iSAC-wb & iSAC-swb in both sides as receiver codecs.
135 EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC16kHz));
136 EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC32kHz));
137 EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC16kHz));
138 EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC32kHz));
niklase@google.com470e71d2011-07-07 08:21:25 +0000139
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000140 //--- Set A-to-B channel
turaj@webrtc.org55e17232013-10-29 04:40:09 +0000141 _channel_A2B.reset(new Channel);
142 EXPECT_EQ(0, _acmA->RegisterTransportCallback(_channel_A2B.get()));
143 _channel_A2B->RegisterReceiverACM(_acmB.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000144
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000145 //--- Set B-to-A channel
turaj@webrtc.org55e17232013-10-29 04:40:09 +0000146 _channel_B2A.reset(new Channel);
147 EXPECT_EQ(0, _acmB->RegisterTransportCallback(_channel_B2A.get()));
148 _channel_B2A->RegisterReceiverACM(_acmA.get());
niklase@google.com470e71d2011-07-07 08:21:25 +0000149
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000150 file_name_swb_ = webrtc::test::ResourcePath("audio_coding/testfile32kHz",
151 "pcm");
niklase@google.com470e71d2011-07-07 08:21:25 +0000152
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000153 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
154 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000155
156 _inFileA.Open(file_name_swb_, 32000, "rb");
157 std::string fileNameA = webrtc::test::OutputPath() + "testisac_a.pcm";
158 std::string fileNameB = webrtc::test::OutputPath() + "testisac_b.pcm";
159 _outFileA.Open(fileNameA, 32000, "wb");
160 _outFileB.Open(fileNameB, 32000, "wb");
161
162 while (!_inFileA.EndOfFile()) {
163 Run10ms();
164 }
165 CodecInst receiveCodec;
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000166 EXPECT_EQ(0, _acmA->ReceiveCodec(&receiveCodec));
167 EXPECT_EQ(0, _acmB->ReceiveCodec(&receiveCodec));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000168
169 _inFileA.Close();
170 _outFileA.Close();
171 _outFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000172}
173
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000174void ISACTest::Perform() {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000175 Setup();
niklase@google.com470e71d2011-07-07 08:21:25 +0000176
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000177 int16_t testNr = 0;
178 ACMTestISACConfig wbISACConfig;
179 ACMTestISACConfig swbISACConfig;
niklase@google.com470e71d2011-07-07 08:21:25 +0000180
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000181 SetISACConfigDefault(wbISACConfig);
182 SetISACConfigDefault(swbISACConfig);
niklase@google.com470e71d2011-07-07 08:21:25 +0000183
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000184 wbISACConfig.currentRateBitPerSec = -1;
185 swbISACConfig.currentRateBitPerSec = -1;
186 testNr++;
187 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
188
189 if (_testMode != 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 SetISACConfigDefault(wbISACConfig);
191 SetISACConfigDefault(swbISACConfig);
192
193 wbISACConfig.currentRateBitPerSec = -1;
194 swbISACConfig.currentRateBitPerSec = -1;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000195 wbISACConfig.initRateBitPerSec = 13000;
196 wbISACConfig.initFrameSizeInMsec = 60;
197 swbISACConfig.initRateBitPerSec = 20000;
198 swbISACConfig.initFrameSizeInMsec = 30;
niklase@google.com470e71d2011-07-07 08:21:25 +0000199 testNr++;
200 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
201
niklase@google.com470e71d2011-07-07 08:21:25 +0000202 SetISACConfigDefault(wbISACConfig);
203 SetISACConfigDefault(swbISACConfig);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000204
205 wbISACConfig.currentRateBitPerSec = 20000;
206 swbISACConfig.currentRateBitPerSec = 48000;
niklase@google.com470e71d2011-07-07 08:21:25 +0000207 testNr++;
208 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000209
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000210 wbISACConfig.currentRateBitPerSec = 16000;
211 swbISACConfig.currentRateBitPerSec = 30000;
212 wbISACConfig.currentFrameSizeMsec = 60;
niklase@google.com470e71d2011-07-07 08:21:25 +0000213 testNr++;
214 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000215 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000216
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000217 SetISACConfigDefault(wbISACConfig);
218 SetISACConfigDefault(swbISACConfig);
219 testNr++;
220 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
niklase@google.com470e71d2011-07-07 08:21:25 +0000221
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000222 int user_input;
223 if ((_testMode == 0) || (_testMode == 1)) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000224 swbISACConfig.maxPayloadSizeByte = static_cast<uint16_t>(200);
225 wbISACConfig.maxPayloadSizeByte = static_cast<uint16_t>(200);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000226 } else {
227 printf("Enter the max payload-size for side A: ");
228 CHECK_ERROR(scanf("%d", &user_input));
229 swbISACConfig.maxPayloadSizeByte = (uint16_t) user_input;
230 printf("Enter the max payload-size for side B: ");
231 CHECK_ERROR(scanf("%d", &user_input));
232 wbISACConfig.maxPayloadSizeByte = (uint16_t) user_input;
233 }
234 testNr++;
235 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
niklase@google.com470e71d2011-07-07 08:21:25 +0000236
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000237 _acmA->ResetEncoder();
238 _acmB->ResetEncoder();
239 SetISACConfigDefault(wbISACConfig);
240 SetISACConfigDefault(swbISACConfig);
niklase@google.com470e71d2011-07-07 08:21:25 +0000241
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000242 if ((_testMode == 0) || (_testMode == 1)) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000243 swbISACConfig.maxRateBitPerSec = static_cast<uint32_t>(48000);
244 wbISACConfig.maxRateBitPerSec = static_cast<uint32_t>(48000);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000245 } else {
246 printf("Enter the max rate for side A: ");
247 CHECK_ERROR(scanf("%d", &user_input));
248 swbISACConfig.maxRateBitPerSec = (uint32_t) user_input;
249 printf("Enter the max rate for side B: ");
250 CHECK_ERROR(scanf("%d", &user_input));
251 wbISACConfig.maxRateBitPerSec = (uint32_t) user_input;
252 }
253
254 testNr++;
255 EncodeDecode(testNr, wbISACConfig, swbISACConfig);
256
257 testNr++;
258 if (_testMode == 0) {
259 SwitchingSamplingRate(testNr, 4);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000260 } else {
261 SwitchingSamplingRate(testNr, 80);
262 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000263}
264
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000265void ISACTest::EncodeDecode(int testNr, ACMTestISACConfig& wbISACConfig,
266 ACMTestISACConfig& swbISACConfig) {
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000267 // Files in Side A and B
268 _inFileA.Open(file_name_swb_, 32000, "rb", true);
269 _inFileB.Open(file_name_swb_, 32000, "rb", true);
270
271 std::string file_name_out;
272 std::stringstream file_stream_a;
273 std::stringstream file_stream_b;
274 file_stream_a << webrtc::test::OutputPath();
275 file_stream_b << webrtc::test::OutputPath();
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000276 file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
277 file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000278 file_name_out = file_stream_a.str();
279 _outFileA.Open(file_name_out, 32000, "wb");
280 file_name_out = file_stream_b.str();
281 _outFileB.Open(file_name_out, 32000, "wb");
282
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000283 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
284 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
285 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz));
286 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000287
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000288 // Side A is sending super-wideband, and side B is sending wideband.
turaj@webrtc.org55e17232013-10-29 04:40:09 +0000289 SetISAConfig(swbISACConfig, _acmA.get(), _testMode);
290 SetISAConfig(wbISACConfig, _acmB.get(), _testMode);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000291
292 bool adaptiveMode = false;
293 if ((swbISACConfig.currentRateBitPerSec == -1)
294 || (wbISACConfig.currentRateBitPerSec == -1)) {
295 adaptiveMode = true;
296 }
297 _myTimer.Reset();
298 _channel_A2B->ResetStats();
299 _channel_B2A->ResetStats();
300
301 char currentTime[500];
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000302 CodecInst sendCodec;
303 EventWrapper* myEvent = EventWrapper::Create();
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000304 EXPECT_TRUE(myEvent->StartTimer(true, 10));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000305 while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
306 Run10ms();
307 _myTimer.Tick10ms();
308 _myTimer.CurrentTimeHMS(currentTime);
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000309
310 if ((adaptiveMode) && (_testMode != 0)) {
311 myEvent->Wait(5000);
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000312 EXPECT_EQ(0, _acmA->SendCodec(&sendCodec));
313 EXPECT_EQ(0, _acmB->SendCodec(&sendCodec));
niklase@google.com470e71d2011-07-07 08:21:25 +0000314 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000315 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000316
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000317 if (_testMode != 0) {
318 printf("\n\nSide A statistics\n\n");
319 _channel_A2B->PrintStats(_paramISAC32kHz);
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000320
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000321 printf("\n\nSide B statistics\n\n");
322 _channel_B2A->PrintStats(_paramISAC16kHz);
323 }
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000324
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000325 _outFileA.Close();
326 _outFileB.Close();
327 _inFileA.Close();
328 _inFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000329}
330
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000331void ISACTest::SwitchingSamplingRate(int testNr, int maxSampRateChange) {
332 // Files in Side A
333 _inFileA.Open(file_name_swb_, 32000, "rb");
334 _inFileB.Open(file_name_swb_, 32000, "rb");
tina.legrand@webrtc.orgba468042012-08-17 10:38:28 +0000335
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000336 std::string file_name_out;
337 std::stringstream file_stream_a;
338 std::stringstream file_stream_b;
339 file_stream_a << webrtc::test::OutputPath();
340 file_stream_b << webrtc::test::OutputPath();
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000341 file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
342 file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000343 file_name_out = file_stream_a.str();
344 _outFileA.Open(file_name_out, 32000, "wb");
345 file_name_out = file_stream_b.str();
346 _outFileB.Open(file_name_out, 32000, "wb");
niklase@google.com470e71d2011-07-07 08:21:25 +0000347
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000348 // Start with side A sending super-wideband and side B seding wideband.
349 // Toggle sending wideband/super-wideband in this test.
350 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
351 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000352
353 int numSendCodecChanged = 0;
354 _myTimer.Reset();
355 char currentTime[50];
356 while (numSendCodecChanged < (maxSampRateChange << 1)) {
357 Run10ms();
358 _myTimer.Tick10ms();
359 _myTimer.CurrentTimeHMS(currentTime);
360 if (_testMode == 2)
361 printf("\r%s", currentTime);
362 if (_inFileA.EndOfFile()) {
363 if (_inFileA.SamplingFrequency() == 16000) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000364 // Switch side A to send super-wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000365 _inFileA.Close();
366 _inFileA.Open(file_name_swb_, 32000, "rb");
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000367 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000368 } else {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000369 // Switch side A to send wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000370 _inFileA.Close();
371 _inFileA.Open(file_name_swb_, 32000, "rb");
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000372 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000373 }
374 numSendCodecChanged++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000375 }
376
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000377 if (_inFileB.EndOfFile()) {
378 if (_inFileB.SamplingFrequency() == 16000) {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000379 // Switch side B to send super-wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000380 _inFileB.Close();
381 _inFileB.Open(file_name_swb_, 32000, "rb");
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000382 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000383 } else {
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000384 // Switch side B to send wideband.
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000385 _inFileB.Close();
386 _inFileB.Open(file_name_swb_, 32000, "rb");
tina.legrand@webrtc.orgee92b662013-08-27 07:33:51 +0000387 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000388 }
389 numSendCodecChanged++;
niklase@google.com470e71d2011-07-07 08:21:25 +0000390 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000391 }
392 _outFileA.Close();
393 _outFileB.Close();
394 _inFileA.Close();
395 _inFileB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +0000396}
turaj@webrtc.org7cc64b32014-01-10 22:35:09 +0000397#else // Only iSAC fixed-point is defined.
398
399static int PayloadSizeToInstantaneousRate(int payload_size_bytes,
400 int frame_size_ms) {
401 return payload_size_bytes * 8 / frame_size_ms / 1000;
402}
403
404void ISACTest::Setup() {
405 CodecInst codec_param;
406 codec_param.plfreq = 0; // Invalid value.
407 for (int n = 0; n < AudioCodingModule::NumberOfCodecs(); ++n) {
408 EXPECT_EQ(0, AudioCodingModule::Codec(n, &codec_param));
409 if (!STR_CASE_CMP(codec_param.plname, "ISAC")) {
410 ASSERT_EQ(16000, codec_param.plfreq);
411 memcpy(&_paramISAC16kHz, &codec_param, sizeof(codec_param));
412 _idISAC16kHz = n;
413 break;
414 }
415 }
416 EXPECT_GT(codec_param.plfreq, 0);
417
418 EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC16kHz));
419 EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC16kHz));
420
421 //--- Set A-to-B channel
422 _channel_A2B.reset(new Channel);
423 EXPECT_EQ(0, _acmA->RegisterTransportCallback(_channel_A2B.get()));
424 _channel_A2B->RegisterReceiverACM(_acmB.get());
425
426 //--- Set B-to-A channel
427 _channel_B2A.reset(new Channel);
428 EXPECT_EQ(0, _acmB->RegisterTransportCallback(_channel_B2A.get()));
429 _channel_B2A->RegisterReceiverACM(_acmA.get());
430
431 file_name_swb_ = webrtc::test::ResourcePath("audio_coding/testfile32kHz",
432 "pcm");
433
434 EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
435 EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
436}
437
438void ISACTest::EncodeDecode(int test_number, ACMTestISACConfig& isac_config_a,
439 ACMTestISACConfig& isac_config_b) {
440 // Files in Side A and B
441 _inFileA.Open(file_name_swb_, 32000, "rb", true);
442 _inFileB.Open(file_name_swb_, 32000, "rb", true);
443
444 std::string file_name_out;
445 std::stringstream file_stream_a;
446 std::stringstream file_stream_b;
447 file_stream_a << webrtc::test::OutputPath();
448 file_stream_b << webrtc::test::OutputPath();
449 file_stream_a << "out_iSACTest_A_" << test_number << ".pcm";
450 file_stream_b << "out_iSACTest_B_" << test_number << ".pcm";
451 file_name_out = file_stream_a.str();
452 _outFileA.Open(file_name_out, 32000, "wb");
453 file_name_out = file_stream_b.str();
454 _outFileB.Open(file_name_out, 32000, "wb");
455
456 CodecInst codec;
457 EXPECT_EQ(0, _acmA->SendCodec(&codec));
458 EXPECT_EQ(0, _acmB->SendCodec(&codec));
459
460 // Set the configurations.
461 SetISAConfig(isac_config_a, _acmA.get(), _testMode);
462 SetISAConfig(isac_config_b, _acmB.get(), _testMode);
463
464 bool adaptiveMode = false;
465 if (isac_config_a.currentRateBitPerSec == -1 ||
466 isac_config_b.currentRateBitPerSec == -1) {
467 adaptiveMode = true;
468 }
469 _channel_A2B->ResetStats();
470 _channel_B2A->ResetStats();
471
472 EventWrapper* myEvent = EventWrapper::Create();
473 EXPECT_TRUE(myEvent->StartTimer(true, 10));
474 while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
475 Run10ms();
476 if (adaptiveMode && _testMode != 0) {
477 myEvent->Wait(5000);
478 }
479 }
480
481 if (_testMode != 0) {
482 printf("\n\nSide A statistics\n\n");
483 _channel_A2B->PrintStats(_paramISAC32kHz);
484
485 printf("\n\nSide B statistics\n\n");
486 _channel_B2A->PrintStats(_paramISAC16kHz);
487 }
488
489 _outFileA.Close();
490 _outFileB.Close();
491 _inFileA.Close();
492 _inFileB.Close();
493}
494
495void ISACTest::Perform() {
496 Setup();
497
498 int16_t test_number = 0;
499 ACMTestISACConfig isac_config_a;
500 ACMTestISACConfig isac_config_b;
501
502 SetISACConfigDefault(isac_config_a);
503 SetISACConfigDefault(isac_config_b);
504
505 // Instantaneous mode.
506 isac_config_a.currentRateBitPerSec = 32000;
507 isac_config_b.currentRateBitPerSec = 12000;
508 EncodeDecode(test_number, isac_config_a, isac_config_b);
509 test_number++;
510
511 SetISACConfigDefault(isac_config_a);
512 SetISACConfigDefault(isac_config_b);
513
514 // Channel adaptive.
515 isac_config_a.currentRateBitPerSec = -1;
516 isac_config_b.currentRateBitPerSec = -1;
517 isac_config_a.initRateBitPerSec = 13000;
518 isac_config_a.initFrameSizeInMsec = 60;
519 isac_config_a.enforceFrameSize = true;
520 isac_config_a.currentFrameSizeMsec = 60;
521 isac_config_b.initRateBitPerSec = 20000;
522 isac_config_b.initFrameSizeInMsec = 30;
523 EncodeDecode(test_number, isac_config_a, isac_config_b);
524 test_number++;
525
526 SetISACConfigDefault(isac_config_a);
527 SetISACConfigDefault(isac_config_b);
528 isac_config_a.currentRateBitPerSec = 32000;
529 isac_config_b.currentRateBitPerSec = 32000;
530 isac_config_a.currentFrameSizeMsec = 30;
531 isac_config_b.currentFrameSizeMsec = 60;
532
533 int user_input;
534 const int kMaxPayloadLenBytes30MSec = 110;
535 const int kMaxPayloadLenBytes60MSec = 160;
536 if ((_testMode == 0) || (_testMode == 1)) {
537 isac_config_a.maxPayloadSizeByte =
538 static_cast<uint16_t>(kMaxPayloadLenBytes30MSec);
539 isac_config_b.maxPayloadSizeByte =
540 static_cast<uint16_t>(kMaxPayloadLenBytes60MSec);
541 } else {
542 printf("Enter the max payload-size for side A: ");
543 CHECK_ERROR(scanf("%d", &user_input));
544 isac_config_a.maxPayloadSizeByte = (uint16_t) user_input;
545 printf("Enter the max payload-size for side B: ");
546 CHECK_ERROR(scanf("%d", &user_input));
547 isac_config_b.maxPayloadSizeByte = (uint16_t) user_input;
548 }
549 EncodeDecode(test_number, isac_config_a, isac_config_b);
550 test_number++;
551
552 ACMTestPayloadStats payload_stats;
553 _channel_A2B->Stats(_paramISAC16kHz, payload_stats);
554 EXPECT_GT(payload_stats.frameSizeStats[0].maxPayloadLen, 0);
555 EXPECT_LE(payload_stats.frameSizeStats[0].maxPayloadLen,
556 static_cast<int>(isac_config_a.maxPayloadSizeByte));
557 _channel_B2A->Stats(_paramISAC16kHz, payload_stats);
558 EXPECT_GT(payload_stats.frameSizeStats[0].maxPayloadLen, 0);
559 EXPECT_LE(payload_stats.frameSizeStats[0].maxPayloadLen,
560 static_cast<int>(isac_config_b.maxPayloadSizeByte));
561
562 _acmA->ResetEncoder();
563 _acmB->ResetEncoder();
564 SetISACConfigDefault(isac_config_a);
565 SetISACConfigDefault(isac_config_b);
566 isac_config_a.currentRateBitPerSec = 32000;
567 isac_config_b.currentRateBitPerSec = 32000;
568 isac_config_a.currentFrameSizeMsec = 30;
569 isac_config_b.currentFrameSizeMsec = 60;
570
571 const int kMaxEncodingRateBitsPerSec = 32000;
572 if ((_testMode == 0) || (_testMode == 1)) {
573 isac_config_a.maxRateBitPerSec =
574 static_cast<uint32_t>(kMaxEncodingRateBitsPerSec);
575 isac_config_b.maxRateBitPerSec =
576 static_cast<uint32_t>(kMaxEncodingRateBitsPerSec);
577 } else {
578 printf("Enter the max rate for side A: ");
579 CHECK_ERROR(scanf("%d", &user_input));
580 isac_config_a.maxRateBitPerSec = (uint32_t) user_input;
581 printf("Enter the max rate for side B: ");
582 CHECK_ERROR(scanf("%d", &user_input));
583 isac_config_b.maxRateBitPerSec = (uint32_t) user_input;
584 }
585 EncodeDecode(test_number, isac_config_a, isac_config_b);
586
587 _channel_A2B->Stats(_paramISAC16kHz, payload_stats);
588 EXPECT_GT(payload_stats.frameSizeStats[0].maxPayloadLen, 0);
589 EXPECT_LE(PayloadSizeToInstantaneousRate(
590 payload_stats.frameSizeStats[0].maxPayloadLen,
591 isac_config_a.currentFrameSizeMsec),
592 static_cast<int>(isac_config_a.maxRateBitPerSec));
593
594 _channel_B2A->Stats(_paramISAC16kHz, payload_stats);
595 EXPECT_GT(payload_stats.frameSizeStats[0].maxPayloadLen, 0);
596 EXPECT_LE(PayloadSizeToInstantaneousRate(
597 payload_stats.frameSizeStats[0].maxPayloadLen,
598 isac_config_b.currentFrameSizeMsec),
599 static_cast<int>(isac_config_b.maxRateBitPerSec));
600}
601#endif // WEBRTC_CODEC_ISAC
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +0000602
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000603} // namespace webrtc