TestStereo.cc (22035B)
1 /* 2 * Copyright (c) 2012 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/test/TestStereo.h" 12 13 #include <cmath> 14 #include <cstddef> 15 #include <cstdint> 16 #include <cstring> 17 #include <string> 18 #include <utility> 19 20 #include "absl/strings/match.h" 21 #include "absl/strings/str_cat.h" 22 #include "api/array_view.h" 23 #include "api/audio/audio_frame.h" 24 #include "api/audio_codecs/audio_format.h" 25 #include "api/audio_codecs/builtin_audio_decoder_factory.h" 26 #include "api/audio_codecs/builtin_audio_encoder_factory.h" 27 #include "api/environment/environment_factory.h" 28 #include "api/neteq/default_neteq_factory.h" 29 #include "api/neteq/neteq.h" 30 #include "api/rtp_headers.h" 31 #include "api/rtp_parameters.h" 32 #include "api/units/timestamp.h" 33 #include "modules/audio_coding/include/audio_coding_module.h" 34 #include "modules/audio_coding/include/audio_coding_module_typedefs.h" 35 #include "modules/audio_coding/test/PCMFile.h" 36 #include "rtc_base/checks.h" 37 #include "rtc_base/strings/string_builder.h" 38 #include "test/gtest.h" 39 #include "test/testsupport/file_utils.h" 40 41 namespace webrtc { 42 43 // Class for simulating packet handling 44 TestPackStereo::TestPackStereo() 45 : neteq_(nullptr), 46 seq_no_(0), 47 timestamp_diff_(0), 48 last_in_timestamp_(0), 49 total_bytes_(0), 50 payload_size_(0), 51 lost_packet_(false) {} 52 53 TestPackStereo::~TestPackStereo() {} 54 55 void TestPackStereo::RegisterReceiverNetEq(NetEq* neteq) { 56 neteq_ = neteq; 57 return; 58 } 59 60 int32_t TestPackStereo::SendData(const AudioFrameType frame_type, 61 const uint8_t payload_type, 62 const uint32_t timestamp, 63 const uint8_t* payload_data, 64 const size_t payload_size, 65 int64_t /* absolute_capture_timestamp_ms */) { 66 RTPHeader rtp_header; 67 int32_t status = 0; 68 69 rtp_header.markerBit = false; 70 rtp_header.ssrc = 0; 71 rtp_header.sequenceNumber = seq_no_++; 72 rtp_header.payloadType = payload_type; 73 rtp_header.timestamp = timestamp; 74 if (frame_type == AudioFrameType::kEmptyFrame) { 75 // Skip this frame 76 return 0; 77 } 78 79 if (lost_packet_ == false) { 80 status = neteq_->InsertPacket( 81 rtp_header, ArrayView<const uint8_t>(payload_data, payload_size), 82 /*receive_time=*/Timestamp::MinusInfinity()); 83 84 if (frame_type != AudioFrameType::kAudioFrameCN) { 85 payload_size_ = static_cast<int>(payload_size); 86 } else { 87 payload_size_ = -1; 88 } 89 90 timestamp_diff_ = timestamp - last_in_timestamp_; 91 last_in_timestamp_ = timestamp; 92 total_bytes_ += payload_size; 93 } 94 return status; 95 } 96 97 uint16_t TestPackStereo::payload_size() { 98 return static_cast<uint16_t>(payload_size_); 99 } 100 101 uint32_t TestPackStereo::timestamp_diff() { 102 return timestamp_diff_; 103 } 104 105 void TestPackStereo::reset_payload_size() { 106 payload_size_ = 0; 107 } 108 109 void TestPackStereo::set_codec_mode(enum StereoMonoMode mode) { 110 codec_mode_ = mode; 111 } 112 113 void TestPackStereo::set_lost_packet(bool lost) { 114 lost_packet_ = lost; 115 } 116 117 TestStereo::TestStereo() 118 : env_(CreateEnvironment()), 119 acm_a_(AudioCodingModule::Create()), 120 neteq_(DefaultNetEqFactory().Create(env_, 121 NetEq::Config(), 122 CreateBuiltinAudioDecoderFactory())), 123 channel_a2b_(nullptr), 124 test_cntr_(0), 125 pack_size_samp_(0), 126 pack_size_bytes_(0), 127 counter_(0) {} 128 129 TestStereo::~TestStereo() { 130 if (channel_a2b_ != nullptr) { 131 delete channel_a2b_; 132 channel_a2b_ = nullptr; 133 } 134 } 135 136 void TestStereo::Perform() { 137 uint16_t frequency_hz; 138 int audio_channels; 139 int codec_channels; 140 141 // Open both mono and stereo test files in 32 kHz. 142 const std::string file_name_stereo = 143 test::ResourcePath("audio_coding/teststereo32kHz", "pcm"); 144 const std::string file_name_mono = 145 test::ResourcePath("audio_coding/testfile32kHz", "pcm"); 146 frequency_hz = 32000; 147 in_file_stereo_ = new PCMFile(); 148 in_file_mono_ = new PCMFile(); 149 in_file_stereo_->Open(file_name_stereo, frequency_hz, "rb"); 150 in_file_stereo_->ReadStereo(true); 151 in_file_mono_->Open(file_name_mono, frequency_hz, "rb"); 152 in_file_mono_->ReadStereo(false); 153 154 // Create and initialize two ACMs, one for each side of a one-to-one call. 155 ASSERT_TRUE((acm_a_.get() != nullptr) && (neteq_.get() != nullptr)); 156 neteq_->FlushBuffers(); 157 158 neteq_->SetCodecs({{103, {"ISAC", 16000, 1}}, 159 {104, {"ISAC", 32000, 1}}, 160 {107, {"L16", 8000, 1}}, 161 {108, {"L16", 16000, 1}}, 162 {109, {"L16", 32000, 1}}, 163 {111, {"L16", 8000, 2}}, 164 {112, {"L16", 16000, 2}}, 165 {113, {"L16", 32000, 2}}, 166 {0, {"PCMU", 8000, 1}}, 167 {110, {"PCMU", 8000, 2}}, 168 {8, {"PCMA", 8000, 1}}, 169 {118, {"PCMA", 8000, 2}}, 170 {9, {"G722", 8000, 1}}, 171 {119, {"G722", 8000, 2}}, 172 {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}, 173 {13, {"CN", 8000, 1}}, 174 {98, {"CN", 16000, 1}}, 175 {99, {"CN", 32000, 1}}}); 176 177 // Create and connect the channel. 178 channel_a2b_ = new TestPackStereo; 179 EXPECT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_)); 180 channel_a2b_->RegisterReceiverNetEq(neteq_.get()); 181 182 char codec_pcma_temp[] = "PCMA"; 183 RegisterSendCodec('A', codec_pcma_temp, 8000, 64000, 80, 2); 184 185 // 186 // Test Stereo-To-Stereo for all codecs. 187 // 188 audio_channels = 2; 189 codec_channels = 2; 190 191 // TODO(bugs.webrtc.org/345525069): Either fix/enable or remove G722. 192 #if defined(__has_feature) && !__has_feature(undefined_behavior_sanitizer) 193 // All codecs are tested for all allowed sampling frequencies, rates and 194 // packet sizes. 195 channel_a2b_->set_codec_mode(kStereo); 196 test_cntr_++; 197 OpenOutFile(test_cntr_); 198 char codec_g722[] = "G722"; 199 RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels); 200 Run(channel_a2b_, audio_channels, codec_channels); 201 RegisterSendCodec('A', codec_g722, 16000, 64000, 320, codec_channels); 202 Run(channel_a2b_, audio_channels, codec_channels); 203 RegisterSendCodec('A', codec_g722, 16000, 64000, 480, codec_channels); 204 Run(channel_a2b_, audio_channels, codec_channels); 205 RegisterSendCodec('A', codec_g722, 16000, 64000, 640, codec_channels); 206 Run(channel_a2b_, audio_channels, codec_channels); 207 RegisterSendCodec('A', codec_g722, 16000, 64000, 800, codec_channels); 208 Run(channel_a2b_, audio_channels, codec_channels); 209 RegisterSendCodec('A', codec_g722, 16000, 64000, 960, codec_channels); 210 Run(channel_a2b_, audio_channels, codec_channels); 211 out_file_.Close(); 212 #endif 213 214 channel_a2b_->set_codec_mode(kStereo); 215 test_cntr_++; 216 OpenOutFile(test_cntr_); 217 char codec_l16[] = "L16"; 218 RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels); 219 Run(channel_a2b_, audio_channels, codec_channels); 220 RegisterSendCodec('A', codec_l16, 8000, 128000, 160, codec_channels); 221 Run(channel_a2b_, audio_channels, codec_channels); 222 RegisterSendCodec('A', codec_l16, 8000, 128000, 240, codec_channels); 223 Run(channel_a2b_, audio_channels, codec_channels); 224 RegisterSendCodec('A', codec_l16, 8000, 128000, 320, codec_channels); 225 Run(channel_a2b_, audio_channels, codec_channels); 226 out_file_.Close(); 227 228 test_cntr_++; 229 OpenOutFile(test_cntr_); 230 RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels); 231 Run(channel_a2b_, audio_channels, codec_channels); 232 RegisterSendCodec('A', codec_l16, 16000, 256000, 320, codec_channels); 233 Run(channel_a2b_, audio_channels, codec_channels); 234 RegisterSendCodec('A', codec_l16, 16000, 256000, 480, codec_channels); 235 Run(channel_a2b_, audio_channels, codec_channels); 236 RegisterSendCodec('A', codec_l16, 16000, 256000, 640, codec_channels); 237 Run(channel_a2b_, audio_channels, codec_channels); 238 out_file_.Close(); 239 240 test_cntr_++; 241 OpenOutFile(test_cntr_); 242 RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels); 243 Run(channel_a2b_, audio_channels, codec_channels); 244 RegisterSendCodec('A', codec_l16, 32000, 512000, 640, codec_channels); 245 Run(channel_a2b_, audio_channels, codec_channels); 246 out_file_.Close(); 247 #ifdef PCMA_AND_PCMU 248 channel_a2b_->set_codec_mode(kStereo); 249 audio_channels = 2; 250 codec_channels = 2; 251 test_cntr_++; 252 OpenOutFile(test_cntr_); 253 char codec_pcma[] = "PCMA"; 254 RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels); 255 Run(channel_a2b_, audio_channels, codec_channels); 256 RegisterSendCodec('A', codec_pcma, 8000, 64000, 160, codec_channels); 257 Run(channel_a2b_, audio_channels, codec_channels); 258 RegisterSendCodec('A', codec_pcma, 8000, 64000, 240, codec_channels); 259 Run(channel_a2b_, audio_channels, codec_channels); 260 RegisterSendCodec('A', codec_pcma, 8000, 64000, 320, codec_channels); 261 Run(channel_a2b_, audio_channels, codec_channels); 262 RegisterSendCodec('A', codec_pcma, 8000, 64000, 400, codec_channels); 263 Run(channel_a2b_, audio_channels, codec_channels); 264 RegisterSendCodec('A', codec_pcma, 8000, 64000, 480, codec_channels); 265 Run(channel_a2b_, audio_channels, codec_channels); 266 out_file_.Close(); 267 268 test_cntr_++; 269 OpenOutFile(test_cntr_); 270 char codec_pcmu[] = "PCMU"; 271 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels); 272 Run(channel_a2b_, audio_channels, codec_channels); 273 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, codec_channels); 274 Run(channel_a2b_, audio_channels, codec_channels); 275 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, codec_channels); 276 Run(channel_a2b_, audio_channels, codec_channels); 277 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, codec_channels); 278 Run(channel_a2b_, audio_channels, codec_channels); 279 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, codec_channels); 280 Run(channel_a2b_, audio_channels, codec_channels); 281 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, codec_channels); 282 Run(channel_a2b_, audio_channels, codec_channels); 283 out_file_.Close(); 284 #endif 285 #ifdef WEBRTC_CODEC_OPUS 286 channel_a2b_->set_codec_mode(kStereo); 287 audio_channels = 2; 288 codec_channels = 2; 289 test_cntr_++; 290 OpenOutFile(test_cntr_); 291 292 char codec_opus[] = "opus"; 293 // Run Opus with 10 ms frame size. 294 RegisterSendCodec('A', codec_opus, 48000, 64000, 480, codec_channels); 295 Run(channel_a2b_, audio_channels, codec_channels); 296 // Run Opus with 20 ms frame size. 297 RegisterSendCodec('A', codec_opus, 48000, 64000, 480 * 2, codec_channels); 298 Run(channel_a2b_, audio_channels, codec_channels); 299 // Run Opus with 40 ms frame size. 300 RegisterSendCodec('A', codec_opus, 48000, 64000, 480 * 4, codec_channels); 301 Run(channel_a2b_, audio_channels, codec_channels); 302 // Run Opus with 60 ms frame size. 303 RegisterSendCodec('A', codec_opus, 48000, 64000, 480 * 6, codec_channels); 304 Run(channel_a2b_, audio_channels, codec_channels); 305 // Run Opus with 20 ms frame size and different bitrates. 306 RegisterSendCodec('A', codec_opus, 48000, 40000, 960, codec_channels); 307 Run(channel_a2b_, audio_channels, codec_channels); 308 RegisterSendCodec('A', codec_opus, 48000, 510000, 960, codec_channels); 309 Run(channel_a2b_, audio_channels, codec_channels); 310 out_file_.Close(); 311 #endif 312 // 313 // Test Mono-To-Stereo for all codecs. 314 // 315 audio_channels = 1; 316 codec_channels = 2; 317 318 // TODO(bugs.webrtc.org/345525069): Either fix/enable or remove G722. 319 #if defined(__has_feature) && !__has_feature(undefined_behavior_sanitizer) 320 test_cntr_++; 321 channel_a2b_->set_codec_mode(kStereo); 322 OpenOutFile(test_cntr_); 323 RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels); 324 Run(channel_a2b_, audio_channels, codec_channels); 325 out_file_.Close(); 326 #endif 327 328 test_cntr_++; 329 channel_a2b_->set_codec_mode(kStereo); 330 OpenOutFile(test_cntr_); 331 RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels); 332 Run(channel_a2b_, audio_channels, codec_channels); 333 out_file_.Close(); 334 335 test_cntr_++; 336 OpenOutFile(test_cntr_); 337 RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels); 338 Run(channel_a2b_, audio_channels, codec_channels); 339 out_file_.Close(); 340 341 test_cntr_++; 342 OpenOutFile(test_cntr_); 343 RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels); 344 Run(channel_a2b_, audio_channels, codec_channels); 345 out_file_.Close(); 346 #ifdef PCMA_AND_PCMU 347 test_cntr_++; 348 channel_a2b_->set_codec_mode(kStereo); 349 OpenOutFile(test_cntr_); 350 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels); 351 Run(channel_a2b_, audio_channels, codec_channels); 352 RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels); 353 Run(channel_a2b_, audio_channels, codec_channels); 354 out_file_.Close(); 355 #endif 356 #ifdef WEBRTC_CODEC_OPUS 357 // Keep encode and decode in stereo. 358 test_cntr_++; 359 channel_a2b_->set_codec_mode(kStereo); 360 OpenOutFile(test_cntr_); 361 RegisterSendCodec('A', codec_opus, 48000, 64000, 960, codec_channels); 362 Run(channel_a2b_, audio_channels, codec_channels); 363 364 // Encode in mono, decode in stereo mode. 365 RegisterSendCodec('A', codec_opus, 48000, 64000, 960, 1); 366 Run(channel_a2b_, audio_channels, codec_channels); 367 out_file_.Close(); 368 #endif 369 370 // 371 // Test Stereo-To-Mono for all codecs. 372 // 373 audio_channels = 2; 374 codec_channels = 1; 375 channel_a2b_->set_codec_mode(kMono); 376 377 // TODO(bugs.webrtc.org/345525069): Either fix/enable or remove G722. 378 #if defined(__has_feature) && !__has_feature(undefined_behavior_sanitizer) 379 // Run stereo audio and mono codec. 380 test_cntr_++; 381 OpenOutFile(test_cntr_); 382 RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels); 383 Run(channel_a2b_, audio_channels, codec_channels); 384 out_file_.Close(); 385 #endif 386 387 test_cntr_++; 388 OpenOutFile(test_cntr_); 389 RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels); 390 Run(channel_a2b_, audio_channels, codec_channels); 391 out_file_.Close(); 392 393 test_cntr_++; 394 OpenOutFile(test_cntr_); 395 RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels); 396 Run(channel_a2b_, audio_channels, codec_channels); 397 out_file_.Close(); 398 399 test_cntr_++; 400 OpenOutFile(test_cntr_); 401 RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels); 402 Run(channel_a2b_, audio_channels, codec_channels); 403 out_file_.Close(); 404 #ifdef PCMA_AND_PCMU 405 test_cntr_++; 406 OpenOutFile(test_cntr_); 407 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels); 408 Run(channel_a2b_, audio_channels, codec_channels); 409 RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels); 410 Run(channel_a2b_, audio_channels, codec_channels); 411 out_file_.Close(); 412 #endif 413 #ifdef WEBRTC_CODEC_OPUS 414 test_cntr_++; 415 OpenOutFile(test_cntr_); 416 // Encode and decode in mono. 417 RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels); 418 neteq_->SetCodecs({{120, {"OPUS", 48000, 2}}}); 419 Run(channel_a2b_, audio_channels, codec_channels); 420 421 // Encode in stereo, decode in mono. 422 RegisterSendCodec('A', codec_opus, 48000, 32000, 960, 2); 423 Run(channel_a2b_, audio_channels, codec_channels); 424 425 out_file_.Close(); 426 427 // Test switching between decoding mono and stereo for Opus. 428 429 // Decode in mono. 430 test_cntr_++; 431 OpenOutFile(test_cntr_); 432 Run(channel_a2b_, audio_channels, codec_channels); 433 out_file_.Close(); 434 // Decode in stereo. 435 test_cntr_++; 436 OpenOutFile(test_cntr_); 437 neteq_->SetCodecs({{120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}}); 438 Run(channel_a2b_, audio_channels, 2); 439 out_file_.Close(); 440 // Decode in mono. 441 test_cntr_++; 442 OpenOutFile(test_cntr_); 443 neteq_->SetCodecs({{120, {"OPUS", 48000, 2}}}); 444 Run(channel_a2b_, audio_channels, codec_channels); 445 out_file_.Close(); 446 #endif 447 448 // Delete the file pointers. 449 delete in_file_stereo_; 450 delete in_file_mono_; 451 } 452 453 // Register Codec to use in the test 454 // 455 // Input: side - which ACM to use, 'A' or 'B' 456 // codec_name - name to use when register the codec 457 // sampling_freq_hz - sampling frequency in Herz 458 // rate - bitrate in bytes 459 // pack_size - packet size in samples 460 // channels - number of channels; 1 for mono, 2 for stereo 461 void TestStereo::RegisterSendCodec(char side, 462 char* codec_name, 463 int32_t sampling_freq_hz, 464 int rate, 465 int pack_size, 466 int channels) { 467 // Store packet size in samples, used to validate the received packet 468 pack_size_samp_ = pack_size; 469 470 // Store the expected packet size in bytes, used to validate the received 471 // packet. Add 0.875 to always round up to a whole byte. 472 pack_size_bytes_ = (uint16_t)(static_cast<float>(pack_size * rate) / 473 static_cast<float>(sampling_freq_hz * 8) + 474 0.875); 475 476 // Set pointer to the ACM where to register the codec 477 AudioCodingModule* my_acm = nullptr; 478 switch (side) { 479 case 'A': { 480 my_acm = acm_a_.get(); 481 break; 482 } 483 case 'B': { 484 // We no longer use this case. Refactor code to avoid the switch. 485 ASSERT_TRUE(false); 486 // my_acm = neteq_.get(); 487 break; 488 } 489 default: 490 break; 491 } 492 ASSERT_TRUE(my_acm != nullptr); 493 494 auto encoder_factory = CreateBuiltinAudioEncoderFactory(); 495 const int clockrate_hz = absl::EqualsIgnoreCase(codec_name, "g722") 496 ? sampling_freq_hz / 2 497 : sampling_freq_hz; 498 const std::string ptime = absl::StrCat( 499 CheckedDivExact(pack_size, CheckedDivExact(sampling_freq_hz, 1000))); 500 CodecParameterMap params = {{"ptime", ptime}}; 501 RTC_CHECK(channels == 1 || channels == 2); 502 if (absl::EqualsIgnoreCase(codec_name, "opus")) { 503 if (channels == 2) { 504 params["stereo"] = "1"; 505 } 506 channels = 2; 507 params["maxaveragebitrate"] = absl::StrCat(rate); 508 } 509 auto encoder = encoder_factory->Create( 510 env_, SdpAudioFormat(codec_name, clockrate_hz, channels, params), 511 {.payload_type = 17}); 512 EXPECT_NE(nullptr, encoder); 513 my_acm->SetEncoder(std::move(encoder)); 514 515 send_codec_name_ = codec_name; 516 } 517 518 void TestStereo::Run(TestPackStereo* channel, 519 int in_channels, 520 int out_channels, 521 int percent_loss) { 522 AudioFrame audio_frame; 523 524 int32_t out_freq_hz_b = out_file_.SamplingFrequency(); 525 uint16_t rec_size; 526 uint32_t time_stamp_diff; 527 channel->reset_payload_size(); 528 int error_count = 0; 529 int variable_bytes = 0; 530 int variable_packets = 0; 531 // Set test length to 500 ms (50 blocks of 10 ms each). 532 in_file_mono_->SetNum10MsBlocksToRead(50); 533 in_file_stereo_->SetNum10MsBlocksToRead(50); 534 // Fast-forward 1 second (100 blocks) since the files start with silence. 535 in_file_stereo_->FastForward(100); 536 in_file_mono_->FastForward(100); 537 538 while (true) { 539 // Simulate packet loss by setting `packet_loss_` to "true" in 540 // `percent_loss` percent of the loops. 541 if (percent_loss > 0) { 542 if (counter_ == floor((100 / percent_loss) + 0.5)) { 543 counter_ = 0; 544 channel->set_lost_packet(true); 545 } else { 546 channel->set_lost_packet(false); 547 } 548 counter_++; 549 } 550 551 // Add 10 msec to ACM 552 if (in_channels == 1) { 553 if (in_file_mono_->EndOfFile()) { 554 break; 555 } 556 in_file_mono_->Read10MsData(audio_frame); 557 } else { 558 if (in_file_stereo_->EndOfFile()) { 559 break; 560 } 561 in_file_stereo_->Read10MsData(audio_frame); 562 } 563 EXPECT_GE(acm_a_->Add10MsData(audio_frame), 0); 564 565 // Verify that the received packet size matches the settings. 566 rec_size = channel->payload_size(); 567 if ((0 < rec_size) & (rec_size < 65535)) { 568 if (strcmp(send_codec_name_, "opus") == 0) { 569 // Opus is a variable rate codec, hence calculate the average packet 570 // size, and later make sure the average is in the right range. 571 variable_bytes += rec_size; 572 variable_packets++; 573 } else { 574 // For fixed rate codecs, check that packet size is correct. 575 if ((rec_size != pack_size_bytes_ * out_channels) && 576 (pack_size_bytes_ < 65535)) { 577 error_count++; 578 } 579 } 580 // Verify that the timestamp is updated with expected length 581 time_stamp_diff = channel->timestamp_diff(); 582 if ((counter_ > 10) && (time_stamp_diff != pack_size_samp_)) { 583 error_count++; 584 } 585 } 586 587 // Run receive side of ACM 588 bool muted; 589 EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&audio_frame, &muted)); 590 EXPECT_TRUE(resampler_helper_.MaybeResample(out_freq_hz_b, &audio_frame)); 591 ASSERT_FALSE(muted); 592 593 // Write output speech to file 594 out_file_.Write10MsData( 595 audio_frame.data(), 596 audio_frame.samples_per_channel_ * audio_frame.num_channels_); 597 } 598 599 EXPECT_EQ(0, error_count); 600 601 // Check that packet size is in the right range for variable rate codecs, 602 // such as Opus. 603 if (variable_packets > 0) { 604 variable_bytes /= variable_packets; 605 EXPECT_NEAR(variable_bytes, pack_size_bytes_, 18); 606 } 607 608 if (in_file_mono_->EndOfFile()) { 609 in_file_mono_->Rewind(); 610 } 611 if (in_file_stereo_->EndOfFile()) { 612 in_file_stereo_->Rewind(); 613 } 614 // Reset in case we ended with a lost packet 615 channel->set_lost_packet(false); 616 } 617 618 void TestStereo::OpenOutFile(int16_t test_number) { 619 std::string file_name; 620 StringBuilder file_stream; 621 file_stream << test::OutputPath() << "teststereo_out_" << test_number 622 << ".pcm"; 623 file_name = file_stream.str(); 624 out_file_.Open(file_name, 32000, "wb"); 625 } 626 627 } // namespace webrtc