Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / main / test / TestStereo.cc
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 "webrtc/modules/audio_coding/main/test/TestStereo.h"
12
13 #include <assert.h>
14
15 #include <string>
16
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webrtc/common_types.h"
19 #include "webrtc/engine_configurations.h"
20 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
21 #include "webrtc/modules/audio_coding/main/test/utility.h"
22 #include "webrtc/system_wrappers/interface/trace.h"
23 #include "webrtc/test/testsupport/fileutils.h"
24
25 namespace webrtc {
26
27 // Class for simulating packet handling
28 TestPackStereo::TestPackStereo()
29     : receiver_acm_(NULL),
30       seq_no_(0),
31       timestamp_diff_(0),
32       last_in_timestamp_(0),
33       total_bytes_(0),
34       payload_size_(0),
35       codec_mode_(kNotSet),
36       lost_packet_(false) {
37 }
38
39 TestPackStereo::~TestPackStereo() {
40 }
41
42 void TestPackStereo::RegisterReceiverACM(AudioCodingModule* acm) {
43   receiver_acm_ = acm;
44   return;
45 }
46
47 int32_t TestPackStereo::SendData(const FrameType frame_type,
48                                  const uint8_t payload_type,
49                                  const uint32_t timestamp,
50                                  const uint8_t* payload_data,
51                                  const uint16_t payload_size,
52                                  const RTPFragmentationHeader* fragmentation) {
53   WebRtcRTPHeader rtp_info;
54   int32_t status = 0;
55
56   rtp_info.header.markerBit = false;
57   rtp_info.header.ssrc = 0;
58   rtp_info.header.sequenceNumber = seq_no_++;
59   rtp_info.header.payloadType = payload_type;
60   rtp_info.header.timestamp = timestamp;
61   if (frame_type == kFrameEmpty) {
62     // Skip this frame
63     return 0;
64   }
65
66   if (lost_packet_ == false) {
67     if (frame_type != kAudioFrameCN) {
68       rtp_info.type.Audio.isCNG = false;
69       rtp_info.type.Audio.channel = static_cast<int>(codec_mode_);
70     } else {
71       rtp_info.type.Audio.isCNG = true;
72       rtp_info.type.Audio.channel = static_cast<int>(kMono);
73     }
74     status = receiver_acm_->IncomingPacket(payload_data, payload_size,
75                                            rtp_info);
76
77     if (frame_type != kAudioFrameCN) {
78       payload_size_ = static_cast<int>(payload_size);
79     } else {
80       payload_size_ = -1;
81     }
82
83     timestamp_diff_ = timestamp - last_in_timestamp_;
84     last_in_timestamp_ = timestamp;
85     total_bytes_ += payload_size;
86   }
87   return status;
88 }
89
90 uint16_t TestPackStereo::payload_size() {
91   return static_cast<uint16_t>(payload_size_);
92 }
93
94 uint32_t TestPackStereo::timestamp_diff() {
95   return timestamp_diff_;
96 }
97
98 void TestPackStereo::reset_payload_size() {
99   payload_size_ = 0;
100 }
101
102 void TestPackStereo::set_codec_mode(enum StereoMonoMode mode) {
103   codec_mode_ = mode;
104 }
105
106 void TestPackStereo::set_lost_packet(bool lost) {
107   lost_packet_ = lost;
108 }
109
110 TestStereo::TestStereo(int test_mode)
111     : acm_a_(AudioCodingModule::Create(0)),
112       acm_b_(AudioCodingModule::Create(1)),
113       channel_a2b_(NULL),
114       test_cntr_(0),
115       pack_size_samp_(0),
116       pack_size_bytes_(0),
117       counter_(0),
118       g722_pltype_(0),
119       l16_8khz_pltype_(-1),
120       l16_16khz_pltype_(-1),
121       l16_32khz_pltype_(-1),
122       pcma_pltype_(-1),
123       pcmu_pltype_(-1),
124       celt_pltype_(-1),
125       opus_pltype_(-1),
126       cn_8khz_pltype_(-1),
127       cn_16khz_pltype_(-1),
128       cn_32khz_pltype_(-1) {
129   // test_mode = 0 for silent test (auto test)
130   test_mode_ = test_mode;
131 }
132
133 TestStereo::~TestStereo() {
134   if (channel_a2b_ != NULL) {
135     delete channel_a2b_;
136     channel_a2b_ = NULL;
137   }
138 }
139
140 void TestStereo::Perform() {
141   uint16_t frequency_hz;
142   int audio_channels;
143   int codec_channels;
144   bool dtx;
145   bool vad;
146   ACMVADMode vad_mode;
147
148   // Open both mono and stereo test files in 32 kHz.
149   const std::string file_name_stereo = webrtc::test::ResourcePath(
150       "audio_coding/teststereo32kHz", "pcm");
151   const std::string file_name_mono = webrtc::test::ResourcePath(
152       "audio_coding/testfile32kHz", "pcm");
153   frequency_hz = 32000;
154   in_file_stereo_ = new PCMFile();
155   in_file_mono_ = new PCMFile();
156   in_file_stereo_->Open(file_name_stereo, frequency_hz, "rb");
157   in_file_stereo_->ReadStereo(true);
158   in_file_mono_->Open(file_name_mono, frequency_hz, "rb");
159   in_file_mono_->ReadStereo(false);
160
161   // Create and initialize two ACMs, one for each side of a one-to-one call.
162   ASSERT_TRUE((acm_a_.get() != NULL) && (acm_b_.get() != NULL));
163   EXPECT_EQ(0, acm_a_->InitializeReceiver());
164   EXPECT_EQ(0, acm_b_->InitializeReceiver());
165
166   // Register all available codes as receiving codecs.
167   uint8_t num_encoders = acm_a_->NumberOfCodecs();
168   CodecInst my_codec_param;
169   for (uint8_t n = 0; n < num_encoders; n++) {
170     EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param));
171     EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param));
172   }
173
174   // Test that unregister all receive codecs works.
175   for (uint8_t n = 0; n < num_encoders; n++) {
176     EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param));
177     EXPECT_EQ(0, acm_b_->UnregisterReceiveCodec(my_codec_param.pltype));
178   }
179
180   // Register all available codes as receiving codecs once more.
181   for (uint8_t n = 0; n < num_encoders; n++) {
182     EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param));
183     EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param));
184   }
185
186   // Create and connect the channel.
187   channel_a2b_ = new TestPackStereo;
188   EXPECT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_));
189   channel_a2b_->RegisterReceiverACM(acm_b_.get());
190
191   // Start with setting VAD/DTX, before we know we will send stereo.
192   // Continue with setting a stereo codec as send codec and verify that
193   // VAD/DTX gets turned off.
194   EXPECT_EQ(0, acm_a_->SetVAD(true, true, VADNormal));
195   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
196   EXPECT_TRUE(dtx);
197   EXPECT_TRUE(vad);
198   char codec_pcma_temp[] = "PCMA";
199   RegisterSendCodec('A', codec_pcma_temp, 8000, 64000, 80, 2, pcma_pltype_);
200   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
201   EXPECT_FALSE(dtx);
202   EXPECT_FALSE(vad);
203   if (test_mode_ != 0) {
204     printf("\n");
205   }
206
207   //
208   // Test Stereo-To-Stereo for all codecs.
209   //
210   audio_channels = 2;
211   codec_channels = 2;
212
213   // All codecs are tested for all allowed sampling frequencies, rates and
214   // packet sizes.
215 #ifdef WEBRTC_CODEC_G722
216   if (test_mode_ != 0) {
217     printf("===========================================================\n");
218     printf("Test number: %d\n", test_cntr_ + 1);
219     printf("Test type: Stereo-to-stereo\n");
220   }
221   channel_a2b_->set_codec_mode(kStereo);
222   test_cntr_++;
223   OpenOutFile(test_cntr_);
224   char codec_g722[] = "G722";
225   RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels,
226       g722_pltype_);
227   Run(channel_a2b_, audio_channels, codec_channels);
228   RegisterSendCodec('A', codec_g722, 16000, 64000, 320, codec_channels,
229       g722_pltype_);
230   Run(channel_a2b_, audio_channels, codec_channels);
231   RegisterSendCodec('A', codec_g722, 16000, 64000, 480, codec_channels,
232       g722_pltype_);
233   Run(channel_a2b_, audio_channels, codec_channels);
234   RegisterSendCodec('A', codec_g722, 16000, 64000, 640, codec_channels,
235       g722_pltype_);
236   Run(channel_a2b_, audio_channels, codec_channels);
237   RegisterSendCodec('A', codec_g722, 16000, 64000, 800, codec_channels,
238       g722_pltype_);
239   Run(channel_a2b_, audio_channels, codec_channels);
240   RegisterSendCodec('A', codec_g722, 16000, 64000, 960, codec_channels,
241       g722_pltype_);
242   Run(channel_a2b_, audio_channels, codec_channels);
243   out_file_.Close();
244 #endif
245 #ifdef WEBRTC_CODEC_PCM16
246   if (test_mode_ != 0) {
247     printf("===========================================================\n");
248     printf("Test number: %d\n", test_cntr_ + 1);
249     printf("Test type: Stereo-to-stereo\n");
250   }
251   channel_a2b_->set_codec_mode(kStereo);
252   test_cntr_++;
253   OpenOutFile(test_cntr_);
254   char codec_l16[] = "L16";
255   RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels,
256       l16_8khz_pltype_);
257   Run(channel_a2b_, audio_channels, codec_channels);
258   RegisterSendCodec('A', codec_l16, 8000, 128000, 160, codec_channels,
259       l16_8khz_pltype_);
260   Run(channel_a2b_, audio_channels, codec_channels);
261   RegisterSendCodec('A', codec_l16, 8000, 128000, 240, codec_channels,
262       l16_8khz_pltype_);
263   Run(channel_a2b_, audio_channels, codec_channels);
264   RegisterSendCodec('A', codec_l16, 8000, 128000, 320, codec_channels,
265       l16_8khz_pltype_);
266   Run(channel_a2b_, audio_channels, codec_channels);
267   out_file_.Close();
268
269   if (test_mode_ != 0) {
270     printf("===========================================================\n");
271     printf("Test number: %d\n", test_cntr_ + 1);
272     printf("Test type: Stereo-to-stereo\n");
273   }
274   test_cntr_++;
275   OpenOutFile(test_cntr_);
276   RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels,
277       l16_16khz_pltype_);
278   Run(channel_a2b_, audio_channels, codec_channels);
279   RegisterSendCodec('A', codec_l16, 16000, 256000, 320, codec_channels,
280       l16_16khz_pltype_);
281   Run(channel_a2b_, audio_channels, codec_channels);
282   RegisterSendCodec('A', codec_l16, 16000, 256000, 480, codec_channels,
283       l16_16khz_pltype_);
284   Run(channel_a2b_, audio_channels, codec_channels);
285   RegisterSendCodec('A', codec_l16, 16000, 256000, 640, codec_channels,
286       l16_16khz_pltype_);
287   Run(channel_a2b_, audio_channels, codec_channels);
288   out_file_.Close();
289
290   if (test_mode_ != 0) {
291     printf("===========================================================\n");
292     printf("Test number: %d\n", test_cntr_ + 1);
293     printf("Test type: Stereo-to-stereo\n");
294   }
295   test_cntr_++;
296   OpenOutFile(test_cntr_);
297   RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels,
298       l16_32khz_pltype_);
299   Run(channel_a2b_, audio_channels, codec_channels);
300   RegisterSendCodec('A', codec_l16, 32000, 512000, 640, codec_channels,
301       l16_32khz_pltype_);
302   Run(channel_a2b_, audio_channels, codec_channels);
303   out_file_.Close();
304 #endif
305 #define PCMA_AND_PCMU
306 #ifdef PCMA_AND_PCMU
307   if (test_mode_ != 0) {
308     printf("===========================================================\n");
309     printf("Test number: %d\n", test_cntr_ + 1);
310     printf("Test type: Stereo-to-stereo\n");
311   }
312   channel_a2b_->set_codec_mode(kStereo);
313   audio_channels = 2;
314   codec_channels = 2;
315   test_cntr_++;
316   OpenOutFile(test_cntr_);
317   char codec_pcma[] = "PCMA";
318   RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels,
319                     pcma_pltype_);
320   Run(channel_a2b_, audio_channels, codec_channels);
321   RegisterSendCodec('A', codec_pcma, 8000, 64000, 160, codec_channels,
322                     pcma_pltype_);
323   Run(channel_a2b_, audio_channels, codec_channels);
324   RegisterSendCodec('A', codec_pcma, 8000, 64000, 240, codec_channels,
325                     pcma_pltype_);
326   Run(channel_a2b_, audio_channels, codec_channels);
327   RegisterSendCodec('A', codec_pcma, 8000, 64000, 320, codec_channels,
328                     pcma_pltype_);
329   Run(channel_a2b_, audio_channels, codec_channels);
330   RegisterSendCodec('A', codec_pcma, 8000, 64000, 400, codec_channels,
331                     pcma_pltype_);
332   Run(channel_a2b_, audio_channels, codec_channels);
333   RegisterSendCodec('A', codec_pcma, 8000, 64000, 480, codec_channels,
334                     pcma_pltype_);
335   Run(channel_a2b_, audio_channels, codec_channels);
336
337   // Test that VAD/DTX cannot be turned on while sending stereo.
338   EXPECT_EQ(-1, acm_a_->SetVAD(true, true, VADNormal));
339   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
340   EXPECT_FALSE(dtx);
341   EXPECT_FALSE(vad);
342   EXPECT_EQ(-1, acm_a_->SetVAD(true, false, VADNormal));
343   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
344   EXPECT_FALSE(dtx);
345   EXPECT_FALSE(vad);
346   EXPECT_EQ(-1, acm_a_->SetVAD(false, true, VADNormal));
347   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
348   EXPECT_FALSE(dtx);
349   EXPECT_FALSE(vad);
350   EXPECT_EQ(0, acm_a_->SetVAD(false, false, VADNormal));
351   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
352   EXPECT_FALSE(dtx);
353   EXPECT_FALSE(vad);
354
355   out_file_.Close();
356   if (test_mode_ != 0) {
357     printf("===========================================================\n");
358     printf("Test number: %d\n", test_cntr_ + 1);
359     printf("Test type: Stereo-to-stereo\n");
360   }
361   test_cntr_++;
362   OpenOutFile(test_cntr_);
363   char codec_pcmu[] = "PCMU";
364   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels,
365                     pcmu_pltype_);
366   Run(channel_a2b_, audio_channels, codec_channels);
367   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, codec_channels,
368                     pcmu_pltype_);
369   Run(channel_a2b_, audio_channels, codec_channels);
370   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, codec_channels,
371                     pcmu_pltype_);
372   Run(channel_a2b_, audio_channels, codec_channels);
373   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, codec_channels,
374                     pcmu_pltype_);
375   Run(channel_a2b_, audio_channels, codec_channels);
376   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, codec_channels,
377                     pcmu_pltype_);
378   Run(channel_a2b_, audio_channels, codec_channels);
379   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, codec_channels,
380                     pcmu_pltype_);
381   Run(channel_a2b_, audio_channels, codec_channels);
382   out_file_.Close();
383 #endif
384 #ifdef WEBRTC_CODEC_CELT
385   if (test_mode_ != 0) {
386     printf("===========================================================\n");
387     printf("Test number: %d\n", test_cntr_ + 1);
388     printf("Test type: Stereo-to-stereo\n");
389   }
390   channel_a2b_->set_codec_mode(kStereo);
391   audio_channels = 2;
392   codec_channels = 2;
393   test_cntr_++;
394   OpenOutFile(test_cntr_);
395   char codec_celt[] = "CELT";
396   RegisterSendCodec('A', codec_celt, 32000, 48000, 640, codec_channels,
397       celt_pltype_);
398   Run(channel_a2b_, audio_channels, codec_channels);
399   RegisterSendCodec('A', codec_celt, 32000, 64000, 640, codec_channels,
400       celt_pltype_);
401   Run(channel_a2b_, audio_channels, codec_channels);
402   RegisterSendCodec('A', codec_celt, 32000, 128000, 640, codec_channels,
403       celt_pltype_);
404   Run(channel_a2b_, audio_channels, codec_channels);
405   out_file_.Close();
406 #endif
407 #ifdef WEBRTC_CODEC_OPUS
408   if (test_mode_ != 0) {
409     printf("===========================================================\n");
410     printf("Test number: %d\n", test_cntr_ + 1);
411     printf("Test type: Stereo-to-stereo\n");
412   }
413   channel_a2b_->set_codec_mode(kStereo);
414   audio_channels = 2;
415   codec_channels = 2;
416   test_cntr_++;
417   OpenOutFile(test_cntr_);
418
419   char codec_opus[] = "opus";
420   // Run Opus with 10 ms frame size.
421   RegisterSendCodec('A', codec_opus, 48000, 64000, 480, codec_channels,
422       opus_pltype_);
423   Run(channel_a2b_, audio_channels, codec_channels);
424   // Run Opus with 20 ms frame size.
425   RegisterSendCodec('A', codec_opus, 48000, 64000, 480*2, codec_channels,
426       opus_pltype_);
427   Run(channel_a2b_, audio_channels, codec_channels);
428   // Run Opus with 40 ms frame size.
429   RegisterSendCodec('A', codec_opus, 48000, 64000, 480*4, codec_channels,
430       opus_pltype_);
431   Run(channel_a2b_, audio_channels, codec_channels);
432   // Run Opus with 60 ms frame size.
433   RegisterSendCodec('A', codec_opus, 48000, 64000, 480*6, codec_channels,
434       opus_pltype_);
435   Run(channel_a2b_, audio_channels, codec_channels);
436   // Run Opus with 20 ms frame size and different bitrates.
437   RegisterSendCodec('A', codec_opus, 48000, 40000, 960, codec_channels,
438       opus_pltype_);
439   Run(channel_a2b_, audio_channels, codec_channels);
440   RegisterSendCodec('A', codec_opus, 48000, 510000, 960, codec_channels,
441       opus_pltype_);
442   Run(channel_a2b_, audio_channels, codec_channels);
443   out_file_.Close();
444 #endif
445   //
446   // Test Mono-To-Stereo for all codecs.
447   //
448   audio_channels = 1;
449   codec_channels = 2;
450
451 #ifdef WEBRTC_CODEC_G722
452   if (test_mode_ != 0) {
453     printf("===============================================================\n");
454     printf("Test number: %d\n", test_cntr_ + 1);
455     printf("Test type: Mono-to-stereo\n");
456   }
457   test_cntr_++;
458   channel_a2b_->set_codec_mode(kStereo);
459   OpenOutFile(test_cntr_);
460   RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels,
461       g722_pltype_);
462   Run(channel_a2b_, audio_channels, codec_channels);
463   out_file_.Close();
464 #endif
465 #ifdef WEBRTC_CODEC_PCM16
466   if (test_mode_ != 0) {
467     printf("===============================================================\n");
468     printf("Test number: %d\n", test_cntr_ + 1);
469     printf("Test type: Mono-to-stereo\n");
470   }
471   test_cntr_++;
472   channel_a2b_->set_codec_mode(kStereo);
473   OpenOutFile(test_cntr_);
474   RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels,
475       l16_8khz_pltype_);
476   Run(channel_a2b_, audio_channels, codec_channels);
477   out_file_.Close();
478   if (test_mode_ != 0) {
479     printf("===============================================================\n");
480     printf("Test number: %d\n", test_cntr_ + 1);
481     printf("Test type: Mono-to-stereo\n");
482   }
483   test_cntr_++;
484   OpenOutFile(test_cntr_);
485   RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels,
486       l16_16khz_pltype_);
487   Run(channel_a2b_, audio_channels, codec_channels);
488   out_file_.Close();
489   if (test_mode_ != 0) {
490     printf("===============================================================\n");
491     printf("Test number: %d\n", test_cntr_ + 1);
492     printf("Test type: Mono-to-stereo\n");
493   }
494   test_cntr_++;
495   OpenOutFile(test_cntr_);
496   RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels,
497       l16_32khz_pltype_);
498   Run(channel_a2b_, audio_channels, codec_channels);
499   out_file_.Close();
500 #endif
501 #ifdef PCMA_AND_PCMU
502   if (test_mode_ != 0) {
503     printf("===============================================================\n");
504     printf("Test number: %d\n", test_cntr_ + 1);
505     printf("Test type: Mono-to-stereo\n");
506   }
507   test_cntr_++;
508   channel_a2b_->set_codec_mode(kStereo);
509   OpenOutFile(test_cntr_);
510   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels,
511                     pcmu_pltype_);
512   Run(channel_a2b_, audio_channels, codec_channels);
513   RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels,
514                     pcma_pltype_);
515   Run(channel_a2b_, audio_channels, codec_channels);
516   out_file_.Close();
517 #endif
518 #ifdef WEBRTC_CODEC_CELT
519   if (test_mode_ != 0) {
520     printf("===============================================================\n");
521     printf("Test number: %d\n", test_cntr_ + 1);
522     printf("Test type: Mono-to-stereo\n");
523   }
524   test_cntr_++;
525   channel_a2b_->set_codec_mode(kStereo);
526   OpenOutFile(test_cntr_);
527   RegisterSendCodec('A', codec_celt, 32000, 64000, 640, codec_channels,
528       celt_pltype_);
529   Run(channel_a2b_, audio_channels, codec_channels);
530   out_file_.Close();
531 #endif
532 #ifdef WEBRTC_CODEC_OPUS
533   if (test_mode_ != 0) {
534     printf("===============================================================\n");
535     printf("Test number: %d\n", test_cntr_ + 1);
536     printf("Test type: Mono-to-stereo\n");
537   }
538
539   // Keep encode and decode in stereo.
540   test_cntr_++;
541   channel_a2b_->set_codec_mode(kStereo);
542   OpenOutFile(test_cntr_);
543   RegisterSendCodec('A', codec_opus, 48000, 64000, 960, codec_channels,
544       opus_pltype_);
545   Run(channel_a2b_, audio_channels, codec_channels);
546
547   // Encode in mono, decode in stereo mode.
548   RegisterSendCodec('A', codec_opus, 48000, 64000, 960, 1, opus_pltype_);
549   Run(channel_a2b_, audio_channels, codec_channels);
550   out_file_.Close();
551 #endif
552
553   //
554   // Test Stereo-To-Mono for all codecs.
555   //
556   audio_channels = 2;
557   codec_channels = 1;
558   channel_a2b_->set_codec_mode(kMono);
559
560 #ifdef WEBRTC_CODEC_G722
561   // Run stereo audio and mono codec.
562   if (test_mode_ != 0) {
563     printf("===============================================================\n");
564     printf("Test number: %d\n", test_cntr_ + 1);
565     printf("Test type: Stereo-to-mono\n");
566   }
567   test_cntr_++;
568   OpenOutFile(test_cntr_);
569   RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels,
570       g722_pltype_);
571
572   // Make sure it is possible to set VAD/CNG, now that we are sending mono
573   // again.
574   EXPECT_EQ(0, acm_a_->SetVAD(true, true, VADNormal));
575   EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode));
576   EXPECT_TRUE(dtx);
577   EXPECT_TRUE(vad);
578   EXPECT_EQ(0, acm_a_->SetVAD(false, false, VADNormal));
579   Run(channel_a2b_, audio_channels, codec_channels);
580   out_file_.Close();
581 #endif
582 #ifdef WEBRTC_CODEC_PCM16
583   if (test_mode_ != 0) {
584     printf("===============================================================\n");
585     printf("Test number: %d\n", test_cntr_ + 1);
586     printf("Test type: Stereo-to-mono\n");
587   }
588   test_cntr_++;
589   OpenOutFile(test_cntr_);
590   RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels,
591       l16_8khz_pltype_);
592   Run(channel_a2b_, audio_channels, codec_channels);
593   out_file_.Close();
594   if (test_mode_ != 0) {
595     printf("===============================================================\n");
596     printf("Test number: %d\n", test_cntr_ + 1);
597     printf("Test type: Stereo-to-mono\n");
598   }
599   test_cntr_++;
600   OpenOutFile(test_cntr_);
601   RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels,
602       l16_16khz_pltype_);
603   Run(channel_a2b_, audio_channels, codec_channels);
604   out_file_.Close();
605   if (test_mode_ != 0) {
606     printf("==============================================================\n");
607     printf("Test number: %d\n", test_cntr_ + 1);
608     printf("Test type: Stereo-to-mono\n");
609   }
610   test_cntr_++;
611   OpenOutFile(test_cntr_);
612   RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels,
613       l16_32khz_pltype_);
614   Run(channel_a2b_, audio_channels, codec_channels);
615   out_file_.Close();
616 #endif
617 #ifdef PCMA_AND_PCMU
618   if (test_mode_ != 0) {
619     printf("===============================================================\n");
620     printf("Test number: %d\n", test_cntr_ + 1);
621     printf("Test type: Stereo-to-mono\n");
622   }
623   test_cntr_++;
624   OpenOutFile(test_cntr_);
625   RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels,
626                     pcmu_pltype_);
627   Run(channel_a2b_, audio_channels, codec_channels);
628   RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels,
629                     pcma_pltype_);
630   Run(channel_a2b_, audio_channels, codec_channels);
631   out_file_.Close();
632 #endif
633 #ifdef WEBRTC_CODEC_CELT
634   if (test_mode_ != 0) {
635     printf("===============================================================\n");
636     printf("Test number: %d\n", test_cntr_ + 1);
637     printf("Test type: Stereo-to-mono\n");
638   }
639   test_cntr_++;
640   OpenOutFile(test_cntr_);
641   RegisterSendCodec('A', codec_celt, 32000, 64000, 640, codec_channels,
642       celt_pltype_);
643   Run(channel_a2b_, audio_channels, codec_channels);
644   out_file_.Close();
645 #endif
646 #ifdef WEBRTC_CODEC_OPUS
647   if (test_mode_ != 0) {
648     printf("===============================================================\n");
649     printf("Test number: %d\n", test_cntr_ + 1);
650     printf("Test type: Stereo-to-mono\n");
651   }
652   test_cntr_++;
653   OpenOutFile(test_cntr_);
654   // Encode and decode in mono.
655   RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels,
656       opus_pltype_);
657   CodecInst opus_codec_param;
658   for (uint8_t n = 0; n < num_encoders; n++) {
659     EXPECT_EQ(0, acm_b_->Codec(n, &opus_codec_param));
660     if (!strcmp(opus_codec_param.plname, "opus")) {
661       opus_codec_param.channels = 1;
662       EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param));
663       break;
664     }
665   }
666   Run(channel_a2b_, audio_channels, codec_channels);
667
668   // Encode in stereo, decode in mono.
669   RegisterSendCodec('A', codec_opus, 48000, 32000, 960, 2, opus_pltype_);
670   Run(channel_a2b_, audio_channels, codec_channels);
671
672   out_file_.Close();
673
674   // Test switching between decoding mono and stereo for Opus.
675
676   // Decode in mono.
677   test_cntr_++;
678   OpenOutFile(test_cntr_);
679   if (test_mode_ != 0) {
680     // Print out codec and settings
681     printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960"
682         " Decode: mono\n", test_cntr_);
683   }
684   Run(channel_a2b_, audio_channels, codec_channels);
685   out_file_.Close();
686   // Decode in stereo.
687   test_cntr_++;
688   OpenOutFile(test_cntr_);
689   if (test_mode_ != 0) {
690     // Print out codec and settings
691     printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960"
692         " Decode: stereo\n", test_cntr_);
693   }
694   opus_codec_param.channels = 2;
695   EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param));
696   Run(channel_a2b_, audio_channels, 2);
697   out_file_.Close();
698   // Decode in mono.
699   test_cntr_++;
700   OpenOutFile(test_cntr_);
701   if (test_mode_ != 0) {
702     // Print out codec and settings
703     printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960"
704         " Decode: mono\n", test_cntr_);
705   }
706   opus_codec_param.channels = 1;
707   EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param));
708   Run(channel_a2b_, audio_channels, codec_channels);
709   out_file_.Close();
710
711 #endif
712
713   // Print out which codecs were tested, and which were not, in the run.
714   if (test_mode_ != 0) {
715     printf("\nThe following codecs was INCLUDED in the test:\n");
716 #ifdef WEBRTC_CODEC_G722
717     printf("   G.722\n");
718 #endif
719 #ifdef WEBRTC_CODEC_PCM16
720     printf("   PCM16\n");
721 #endif
722     printf("   G.711\n");
723 #ifdef WEBRTC_CODEC_CELT
724     printf("   CELT\n");
725 #endif
726 #ifdef WEBRTC_CODEC_OPUS
727     printf("   Opus\n");
728 #endif
729     printf("\nTo complete the test, listen to the %d number of output "
730            "files.\n",
731            test_cntr_);
732   }
733
734   // Delete the file pointers.
735   delete in_file_stereo_;
736   delete in_file_mono_;
737 }
738
739 // Register Codec to use in the test
740 //
741 // Input:   side             - which ACM to use, 'A' or 'B'
742 //          codec_name       - name to use when register the codec
743 //          sampling_freq_hz - sampling frequency in Herz
744 //          rate             - bitrate in bytes
745 //          pack_size        - packet size in samples
746 //          channels         - number of channels; 1 for mono, 2 for stereo
747 //          payload_type     - payload type for the codec
748 void TestStereo::RegisterSendCodec(char side, char* codec_name,
749                                    int32_t sampling_freq_hz, int rate,
750                                    int pack_size, int channels,
751                                    int payload_type) {
752   if (test_mode_ != 0) {
753     // Print out codec and settings
754     printf("Codec: %s Freq: %d Rate: %d PackSize: %d\n", codec_name,
755            sampling_freq_hz, rate, pack_size);
756   }
757
758   // Store packet size in samples, used to validate the received packet
759   pack_size_samp_ = pack_size;
760
761   // Store the expected packet size in bytes, used to validate the received
762   // packet. Add 0.875 to always round up to a whole byte.
763   // For Celt the packet size in bytes is already counting the stereo part.
764   if (!strcmp(codec_name, "CELT")) {
765     pack_size_bytes_ = (uint16_t)(
766         static_cast<float>(pack_size * rate) /
767             static_cast<float>(sampling_freq_hz * 8) + 0.875) / channels;
768   } else {
769     pack_size_bytes_ = (uint16_t)(
770         static_cast<float>(pack_size * rate) /
771             static_cast<float>(sampling_freq_hz * 8) + 0.875);
772   }
773
774   // Set pointer to the ACM where to register the codec
775   AudioCodingModule* my_acm = NULL;
776   switch (side) {
777     case 'A': {
778       my_acm = acm_a_.get();
779       break;
780     }
781     case 'B': {
782       my_acm = acm_b_.get();
783       break;
784     }
785     default:
786       break;
787   }
788   ASSERT_TRUE(my_acm != NULL);
789
790   CodecInst my_codec_param;
791   // Get all codec parameters before registering
792   EXPECT_GT(AudioCodingModule::Codec(codec_name, &my_codec_param,
793                                      sampling_freq_hz, channels), -1);
794   my_codec_param.rate = rate;
795   my_codec_param.pacsize = pack_size;
796   EXPECT_EQ(0, my_acm->RegisterSendCodec(my_codec_param));
797
798   send_codec_name_ = codec_name;
799 }
800
801 void TestStereo::Run(TestPackStereo* channel, int in_channels, int out_channels,
802                      int percent_loss) {
803   AudioFrame audio_frame;
804
805   int32_t out_freq_hz_b = out_file_.SamplingFrequency();
806   uint16_t rec_size;
807   uint32_t time_stamp_diff;
808   channel->reset_payload_size();
809   int error_count = 0;
810   int variable_bytes = 0;
811   int variable_packets = 0;
812
813   while (1) {
814     // Simulate packet loss by setting |packet_loss_| to "true" in
815     // |percent_loss| percent of the loops.
816     if (percent_loss > 0) {
817       if (counter_ == floor((100 / percent_loss) + 0.5)) {
818         counter_ = 0;
819         channel->set_lost_packet(true);
820       } else {
821         channel->set_lost_packet(false);
822       }
823       counter_++;
824     }
825
826     // Add 10 msec to ACM
827     if (in_channels == 1) {
828       if (in_file_mono_->EndOfFile()) {
829         break;
830       }
831       in_file_mono_->Read10MsData(audio_frame);
832     } else {
833       if (in_file_stereo_->EndOfFile()) {
834         break;
835       }
836       in_file_stereo_->Read10MsData(audio_frame);
837     }
838     EXPECT_EQ(0, acm_a_->Add10MsData(audio_frame));
839
840     // Run sender side of ACM
841     EXPECT_GT(acm_a_->Process(), -1);
842
843     // Verify that the received packet size matches the settings.
844     rec_size = channel->payload_size();
845     if ((0 < rec_size) & (rec_size < 65535)) {
846       if (strcmp(send_codec_name_, "opus") == 0) {
847         // Opus is a variable rate codec, hence calculate the average packet
848         // size, and later make sure the average is in the right range.
849         variable_bytes += rec_size;
850         variable_packets++;
851       } else {
852         // For fixed rate codecs, check that packet size is correct.
853         if ((rec_size != pack_size_bytes_ * out_channels)
854             && (pack_size_bytes_ < 65535)) {
855           error_count++;
856         }
857       }
858       // Verify that the timestamp is updated with expected length
859       time_stamp_diff = channel->timestamp_diff();
860       if ((counter_ > 10) && (time_stamp_diff != pack_size_samp_)) {
861         error_count++;
862       }
863     }
864
865     // Run received side of ACM
866     EXPECT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame));
867
868     // Write output speech to file
869     out_file_.Write10MsData(
870         audio_frame.data_,
871         audio_frame.samples_per_channel_ * audio_frame.num_channels_);
872   }
873
874   EXPECT_EQ(0, error_count);
875
876   // Check that packet size is in the right range for variable rate codecs,
877   // such as Opus.
878   if (variable_packets > 0) {
879     variable_bytes /= variable_packets;
880     EXPECT_NEAR(variable_bytes, pack_size_bytes_, 3);
881   }
882
883   if (in_file_mono_->EndOfFile()) {
884     in_file_mono_->Rewind();
885   }
886   if (in_file_stereo_->EndOfFile()) {
887     in_file_stereo_->Rewind();
888   }
889   // Reset in case we ended with a lost packet
890   channel->set_lost_packet(false);
891 }
892
893 void TestStereo::OpenOutFile(int16_t test_number) {
894   std::string file_name;
895   std::stringstream file_stream;
896   file_stream << webrtc::test::OutputPath() << "teststereo_out_" << test_number
897       << ".pcm";
898   file_name = file_stream.str();
899   out_file_.Open(file_name, 32000, "wb");
900 }
901
902 void TestStereo::DisplaySendReceiveCodec() {
903   CodecInst my_codec_param;
904   acm_a_->SendCodec(&my_codec_param);
905   if (test_mode_ != 0) {
906     printf("%s -> ", my_codec_param.plname);
907   }
908   acm_b_->ReceiveCodec(&my_codec_param);
909   if (test_mode_ != 0) {
910     printf("%s\n", my_codec_param.plname);
911   }
912 }
913
914 }  // namespace webrtc