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