OLD | NEW |
| (Empty) |
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/include/audio_coding_module_typedefs.
h" | |
21 #include "webrtc/modules/audio_coding/main/test/utility.h" | |
22 #include "webrtc/system_wrappers/include/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 size_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 == kEmptyFrame) { | |
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 #ifdef WEBRTC_CODEC_G722 | |
119 , g722_pltype_(0) | |
120 #endif | |
121 , l16_8khz_pltype_(-1) | |
122 , l16_16khz_pltype_(-1) | |
123 , l16_32khz_pltype_(-1) | |
124 #ifdef PCMA_AND_PCMU | |
125 , pcma_pltype_(-1) | |
126 , pcmu_pltype_(-1) | |
127 #endif | |
128 #ifdef WEBRTC_CODEC_OPUS | |
129 , opus_pltype_(-1) | |
130 #endif | |
131 { | |
132 // test_mode = 0 for silent test (auto test) | |
133 test_mode_ = test_mode; | |
134 } | |
135 | |
136 TestStereo::~TestStereo() { | |
137 if (channel_a2b_ != NULL) { | |
138 delete channel_a2b_; | |
139 channel_a2b_ = NULL; | |
140 } | |
141 } | |
142 | |
143 void TestStereo::Perform() { | |
144 uint16_t frequency_hz; | |
145 int audio_channels; | |
146 int codec_channels; | |
147 bool dtx; | |
148 bool vad; | |
149 ACMVADMode vad_mode; | |
150 | |
151 // Open both mono and stereo test files in 32 kHz. | |
152 const std::string file_name_stereo = webrtc::test::ResourcePath( | |
153 "audio_coding/teststereo32kHz", "pcm"); | |
154 const std::string file_name_mono = webrtc::test::ResourcePath( | |
155 "audio_coding/testfile32kHz", "pcm"); | |
156 frequency_hz = 32000; | |
157 in_file_stereo_ = new PCMFile(); | |
158 in_file_mono_ = new PCMFile(); | |
159 in_file_stereo_->Open(file_name_stereo, frequency_hz, "rb"); | |
160 in_file_stereo_->ReadStereo(true); | |
161 in_file_mono_->Open(file_name_mono, frequency_hz, "rb"); | |
162 in_file_mono_->ReadStereo(false); | |
163 | |
164 // Create and initialize two ACMs, one for each side of a one-to-one call. | |
165 ASSERT_TRUE((acm_a_.get() != NULL) && (acm_b_.get() != NULL)); | |
166 EXPECT_EQ(0, acm_a_->InitializeReceiver()); | |
167 EXPECT_EQ(0, acm_b_->InitializeReceiver()); | |
168 | |
169 // Register all available codes as receiving codecs. | |
170 uint8_t num_encoders = acm_a_->NumberOfCodecs(); | |
171 CodecInst my_codec_param; | |
172 for (uint8_t n = 0; n < num_encoders; n++) { | |
173 EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)); | |
174 EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param)); | |
175 } | |
176 | |
177 // Test that unregister all receive codecs works. | |
178 for (uint8_t n = 0; n < num_encoders; n++) { | |
179 EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)); | |
180 EXPECT_EQ(0, acm_b_->UnregisterReceiveCodec(my_codec_param.pltype)); | |
181 } | |
182 | |
183 // Register all available codes as receiving codecs once more. | |
184 for (uint8_t n = 0; n < num_encoders; n++) { | |
185 EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)); | |
186 EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param)); | |
187 } | |
188 | |
189 // Create and connect the channel. | |
190 channel_a2b_ = new TestPackStereo; | |
191 EXPECT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_)); | |
192 channel_a2b_->RegisterReceiverACM(acm_b_.get()); | |
193 | |
194 // Start with setting VAD/DTX, before we know we will send stereo. | |
195 // Continue with setting a stereo codec as send codec and verify that | |
196 // VAD/DTX gets turned off. | |
197 EXPECT_EQ(0, acm_a_->SetVAD(true, true, VADNormal)); | |
198 EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); | |
199 EXPECT_TRUE(dtx); | |
200 EXPECT_TRUE(vad); | |
201 char codec_pcma_temp[] = "PCMA"; | |
202 RegisterSendCodec('A', codec_pcma_temp, 8000, 64000, 80, 2, pcma_pltype_); | |
203 EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); | |
204 EXPECT_FALSE(dtx); | |
205 EXPECT_FALSE(vad); | |
206 if (test_mode_ != 0) { | |
207 printf("\n"); | |
208 } | |
209 | |
210 // | |
211 // Test Stereo-To-Stereo for all codecs. | |
212 // | |
213 audio_channels = 2; | |
214 codec_channels = 2; | |
215 | |
216 // All codecs are tested for all allowed sampling frequencies, rates and | |
217 // packet sizes. | |
218 #ifdef WEBRTC_CODEC_G722 | |
219 if (test_mode_ != 0) { | |
220 printf("===========================================================\n"); | |
221 printf("Test number: %d\n", test_cntr_ + 1); | |
222 printf("Test type: Stereo-to-stereo\n"); | |
223 } | |
224 channel_a2b_->set_codec_mode(kStereo); | |
225 test_cntr_++; | |
226 OpenOutFile(test_cntr_); | |
227 char codec_g722[] = "G722"; | |
228 RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels, | |
229 g722_pltype_); | |
230 Run(channel_a2b_, audio_channels, codec_channels); | |
231 RegisterSendCodec('A', codec_g722, 16000, 64000, 320, codec_channels, | |
232 g722_pltype_); | |
233 Run(channel_a2b_, audio_channels, codec_channels); | |
234 RegisterSendCodec('A', codec_g722, 16000, 64000, 480, codec_channels, | |
235 g722_pltype_); | |
236 Run(channel_a2b_, audio_channels, codec_channels); | |
237 RegisterSendCodec('A', codec_g722, 16000, 64000, 640, codec_channels, | |
238 g722_pltype_); | |
239 Run(channel_a2b_, audio_channels, codec_channels); | |
240 RegisterSendCodec('A', codec_g722, 16000, 64000, 800, codec_channels, | |
241 g722_pltype_); | |
242 Run(channel_a2b_, audio_channels, codec_channels); | |
243 RegisterSendCodec('A', codec_g722, 16000, 64000, 960, codec_channels, | |
244 g722_pltype_); | |
245 Run(channel_a2b_, audio_channels, codec_channels); | |
246 out_file_.Close(); | |
247 #endif | |
248 if (test_mode_ != 0) { | |
249 printf("===========================================================\n"); | |
250 printf("Test number: %d\n", test_cntr_ + 1); | |
251 printf("Test type: Stereo-to-stereo\n"); | |
252 } | |
253 channel_a2b_->set_codec_mode(kStereo); | |
254 test_cntr_++; | |
255 OpenOutFile(test_cntr_); | |
256 char codec_l16[] = "L16"; | |
257 RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels, | |
258 l16_8khz_pltype_); | |
259 Run(channel_a2b_, audio_channels, codec_channels); | |
260 RegisterSendCodec('A', codec_l16, 8000, 128000, 160, codec_channels, | |
261 l16_8khz_pltype_); | |
262 Run(channel_a2b_, audio_channels, codec_channels); | |
263 RegisterSendCodec('A', codec_l16, 8000, 128000, 240, codec_channels, | |
264 l16_8khz_pltype_); | |
265 Run(channel_a2b_, audio_channels, codec_channels); | |
266 RegisterSendCodec('A', codec_l16, 8000, 128000, 320, codec_channels, | |
267 l16_8khz_pltype_); | |
268 Run(channel_a2b_, audio_channels, codec_channels); | |
269 out_file_.Close(); | |
270 | |
271 if (test_mode_ != 0) { | |
272 printf("===========================================================\n"); | |
273 printf("Test number: %d\n", test_cntr_ + 1); | |
274 printf("Test type: Stereo-to-stereo\n"); | |
275 } | |
276 test_cntr_++; | |
277 OpenOutFile(test_cntr_); | |
278 RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels, | |
279 l16_16khz_pltype_); | |
280 Run(channel_a2b_, audio_channels, codec_channels); | |
281 RegisterSendCodec('A', codec_l16, 16000, 256000, 320, codec_channels, | |
282 l16_16khz_pltype_); | |
283 Run(channel_a2b_, audio_channels, codec_channels); | |
284 RegisterSendCodec('A', codec_l16, 16000, 256000, 480, codec_channels, | |
285 l16_16khz_pltype_); | |
286 Run(channel_a2b_, audio_channels, codec_channels); | |
287 RegisterSendCodec('A', codec_l16, 16000, 256000, 640, codec_channels, | |
288 l16_16khz_pltype_); | |
289 Run(channel_a2b_, audio_channels, codec_channels); | |
290 out_file_.Close(); | |
291 | |
292 if (test_mode_ != 0) { | |
293 printf("===========================================================\n"); | |
294 printf("Test number: %d\n", test_cntr_ + 1); | |
295 printf("Test type: Stereo-to-stereo\n"); | |
296 } | |
297 test_cntr_++; | |
298 OpenOutFile(test_cntr_); | |
299 RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels, | |
300 l16_32khz_pltype_); | |
301 Run(channel_a2b_, audio_channels, codec_channels); | |
302 RegisterSendCodec('A', codec_l16, 32000, 512000, 640, codec_channels, | |
303 l16_32khz_pltype_); | |
304 Run(channel_a2b_, audio_channels, codec_channels); | |
305 out_file_.Close(); | |
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(0, acm_a_->SetVAD(false, false, VADNormal)); | |
343 EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); | |
344 EXPECT_FALSE(dtx); | |
345 EXPECT_FALSE(vad); | |
346 | |
347 out_file_.Close(); | |
348 if (test_mode_ != 0) { | |
349 printf("===========================================================\n"); | |
350 printf("Test number: %d\n", test_cntr_ + 1); | |
351 printf("Test type: Stereo-to-stereo\n"); | |
352 } | |
353 test_cntr_++; | |
354 OpenOutFile(test_cntr_); | |
355 char codec_pcmu[] = "PCMU"; | |
356 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels, | |
357 pcmu_pltype_); | |
358 Run(channel_a2b_, audio_channels, codec_channels); | |
359 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, codec_channels, | |
360 pcmu_pltype_); | |
361 Run(channel_a2b_, audio_channels, codec_channels); | |
362 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, codec_channels, | |
363 pcmu_pltype_); | |
364 Run(channel_a2b_, audio_channels, codec_channels); | |
365 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, codec_channels, | |
366 pcmu_pltype_); | |
367 Run(channel_a2b_, audio_channels, codec_channels); | |
368 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, codec_channels, | |
369 pcmu_pltype_); | |
370 Run(channel_a2b_, audio_channels, codec_channels); | |
371 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, codec_channels, | |
372 pcmu_pltype_); | |
373 Run(channel_a2b_, audio_channels, codec_channels); | |
374 out_file_.Close(); | |
375 #endif | |
376 #ifdef WEBRTC_CODEC_OPUS | |
377 if (test_mode_ != 0) { | |
378 printf("===========================================================\n"); | |
379 printf("Test number: %d\n", test_cntr_ + 1); | |
380 printf("Test type: Stereo-to-stereo\n"); | |
381 } | |
382 channel_a2b_->set_codec_mode(kStereo); | |
383 audio_channels = 2; | |
384 codec_channels = 2; | |
385 test_cntr_++; | |
386 OpenOutFile(test_cntr_); | |
387 | |
388 char codec_opus[] = "opus"; | |
389 // Run Opus with 10 ms frame size. | |
390 RegisterSendCodec('A', codec_opus, 48000, 64000, 480, codec_channels, | |
391 opus_pltype_); | |
392 Run(channel_a2b_, audio_channels, codec_channels); | |
393 // Run Opus with 20 ms frame size. | |
394 RegisterSendCodec('A', codec_opus, 48000, 64000, 480*2, codec_channels, | |
395 opus_pltype_); | |
396 Run(channel_a2b_, audio_channels, codec_channels); | |
397 // Run Opus with 40 ms frame size. | |
398 RegisterSendCodec('A', codec_opus, 48000, 64000, 480*4, codec_channels, | |
399 opus_pltype_); | |
400 Run(channel_a2b_, audio_channels, codec_channels); | |
401 // Run Opus with 60 ms frame size. | |
402 RegisterSendCodec('A', codec_opus, 48000, 64000, 480*6, codec_channels, | |
403 opus_pltype_); | |
404 Run(channel_a2b_, audio_channels, codec_channels); | |
405 // Run Opus with 20 ms frame size and different bitrates. | |
406 RegisterSendCodec('A', codec_opus, 48000, 40000, 960, codec_channels, | |
407 opus_pltype_); | |
408 Run(channel_a2b_, audio_channels, codec_channels); | |
409 RegisterSendCodec('A', codec_opus, 48000, 510000, 960, codec_channels, | |
410 opus_pltype_); | |
411 Run(channel_a2b_, audio_channels, codec_channels); | |
412 out_file_.Close(); | |
413 #endif | |
414 // | |
415 // Test Mono-To-Stereo for all codecs. | |
416 // | |
417 audio_channels = 1; | |
418 codec_channels = 2; | |
419 | |
420 #ifdef WEBRTC_CODEC_G722 | |
421 if (test_mode_ != 0) { | |
422 printf("===============================================================\n"); | |
423 printf("Test number: %d\n", test_cntr_ + 1); | |
424 printf("Test type: Mono-to-stereo\n"); | |
425 } | |
426 test_cntr_++; | |
427 channel_a2b_->set_codec_mode(kStereo); | |
428 OpenOutFile(test_cntr_); | |
429 RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels, | |
430 g722_pltype_); | |
431 Run(channel_a2b_, audio_channels, codec_channels); | |
432 out_file_.Close(); | |
433 #endif | |
434 if (test_mode_ != 0) { | |
435 printf("===============================================================\n"); | |
436 printf("Test number: %d\n", test_cntr_ + 1); | |
437 printf("Test type: Mono-to-stereo\n"); | |
438 } | |
439 test_cntr_++; | |
440 channel_a2b_->set_codec_mode(kStereo); | |
441 OpenOutFile(test_cntr_); | |
442 RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels, | |
443 l16_8khz_pltype_); | |
444 Run(channel_a2b_, audio_channels, codec_channels); | |
445 out_file_.Close(); | |
446 if (test_mode_ != 0) { | |
447 printf("===============================================================\n"); | |
448 printf("Test number: %d\n", test_cntr_ + 1); | |
449 printf("Test type: Mono-to-stereo\n"); | |
450 } | |
451 test_cntr_++; | |
452 OpenOutFile(test_cntr_); | |
453 RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels, | |
454 l16_16khz_pltype_); | |
455 Run(channel_a2b_, audio_channels, codec_channels); | |
456 out_file_.Close(); | |
457 if (test_mode_ != 0) { | |
458 printf("===============================================================\n"); | |
459 printf("Test number: %d\n", test_cntr_ + 1); | |
460 printf("Test type: Mono-to-stereo\n"); | |
461 } | |
462 test_cntr_++; | |
463 OpenOutFile(test_cntr_); | |
464 RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels, | |
465 l16_32khz_pltype_); | |
466 Run(channel_a2b_, audio_channels, codec_channels); | |
467 out_file_.Close(); | |
468 #ifdef PCMA_AND_PCMU | |
469 if (test_mode_ != 0) { | |
470 printf("===============================================================\n"); | |
471 printf("Test number: %d\n", test_cntr_ + 1); | |
472 printf("Test type: Mono-to-stereo\n"); | |
473 } | |
474 test_cntr_++; | |
475 channel_a2b_->set_codec_mode(kStereo); | |
476 OpenOutFile(test_cntr_); | |
477 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels, | |
478 pcmu_pltype_); | |
479 Run(channel_a2b_, audio_channels, codec_channels); | |
480 RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels, | |
481 pcma_pltype_); | |
482 Run(channel_a2b_, audio_channels, codec_channels); | |
483 out_file_.Close(); | |
484 #endif | |
485 #ifdef WEBRTC_CODEC_OPUS | |
486 if (test_mode_ != 0) { | |
487 printf("===============================================================\n"); | |
488 printf("Test number: %d\n", test_cntr_ + 1); | |
489 printf("Test type: Mono-to-stereo\n"); | |
490 } | |
491 | |
492 // Keep encode and decode in stereo. | |
493 test_cntr_++; | |
494 channel_a2b_->set_codec_mode(kStereo); | |
495 OpenOutFile(test_cntr_); | |
496 RegisterSendCodec('A', codec_opus, 48000, 64000, 960, codec_channels, | |
497 opus_pltype_); | |
498 Run(channel_a2b_, audio_channels, codec_channels); | |
499 | |
500 // Encode in mono, decode in stereo mode. | |
501 RegisterSendCodec('A', codec_opus, 48000, 64000, 960, 1, opus_pltype_); | |
502 Run(channel_a2b_, audio_channels, codec_channels); | |
503 out_file_.Close(); | |
504 #endif | |
505 | |
506 // | |
507 // Test Stereo-To-Mono for all codecs. | |
508 // | |
509 audio_channels = 2; | |
510 codec_channels = 1; | |
511 channel_a2b_->set_codec_mode(kMono); | |
512 | |
513 #ifdef WEBRTC_CODEC_G722 | |
514 // Run stereo audio and mono codec. | |
515 if (test_mode_ != 0) { | |
516 printf("===============================================================\n"); | |
517 printf("Test number: %d\n", test_cntr_ + 1); | |
518 printf("Test type: Stereo-to-mono\n"); | |
519 } | |
520 test_cntr_++; | |
521 OpenOutFile(test_cntr_); | |
522 RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels, | |
523 g722_pltype_); | |
524 | |
525 // Make sure it is possible to set VAD/CNG, now that we are sending mono | |
526 // again. | |
527 EXPECT_EQ(0, acm_a_->SetVAD(true, true, VADNormal)); | |
528 EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); | |
529 EXPECT_TRUE(dtx); | |
530 EXPECT_TRUE(vad); | |
531 EXPECT_EQ(0, acm_a_->SetVAD(false, false, VADNormal)); | |
532 Run(channel_a2b_, audio_channels, codec_channels); | |
533 out_file_.Close(); | |
534 #endif | |
535 if (test_mode_ != 0) { | |
536 printf("===============================================================\n"); | |
537 printf("Test number: %d\n", test_cntr_ + 1); | |
538 printf("Test type: Stereo-to-mono\n"); | |
539 } | |
540 test_cntr_++; | |
541 OpenOutFile(test_cntr_); | |
542 RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels, | |
543 l16_8khz_pltype_); | |
544 Run(channel_a2b_, audio_channels, codec_channels); | |
545 out_file_.Close(); | |
546 if (test_mode_ != 0) { | |
547 printf("===============================================================\n"); | |
548 printf("Test number: %d\n", test_cntr_ + 1); | |
549 printf("Test type: Stereo-to-mono\n"); | |
550 } | |
551 test_cntr_++; | |
552 OpenOutFile(test_cntr_); | |
553 RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels, | |
554 l16_16khz_pltype_); | |
555 Run(channel_a2b_, audio_channels, codec_channels); | |
556 out_file_.Close(); | |
557 if (test_mode_ != 0) { | |
558 printf("==============================================================\n"); | |
559 printf("Test number: %d\n", test_cntr_ + 1); | |
560 printf("Test type: Stereo-to-mono\n"); | |
561 } | |
562 test_cntr_++; | |
563 OpenOutFile(test_cntr_); | |
564 RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels, | |
565 l16_32khz_pltype_); | |
566 Run(channel_a2b_, audio_channels, codec_channels); | |
567 out_file_.Close(); | |
568 #ifdef PCMA_AND_PCMU | |
569 if (test_mode_ != 0) { | |
570 printf("===============================================================\n"); | |
571 printf("Test number: %d\n", test_cntr_ + 1); | |
572 printf("Test type: Stereo-to-mono\n"); | |
573 } | |
574 test_cntr_++; | |
575 OpenOutFile(test_cntr_); | |
576 RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels, | |
577 pcmu_pltype_); | |
578 Run(channel_a2b_, audio_channels, codec_channels); | |
579 RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels, | |
580 pcma_pltype_); | |
581 Run(channel_a2b_, audio_channels, codec_channels); | |
582 out_file_.Close(); | |
583 #endif | |
584 #ifdef WEBRTC_CODEC_OPUS | |
585 if (test_mode_ != 0) { | |
586 printf("===============================================================\n"); | |
587 printf("Test number: %d\n", test_cntr_ + 1); | |
588 printf("Test type: Stereo-to-mono\n"); | |
589 } | |
590 test_cntr_++; | |
591 OpenOutFile(test_cntr_); | |
592 // Encode and decode in mono. | |
593 RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels, | |
594 opus_pltype_); | |
595 CodecInst opus_codec_param; | |
596 for (uint8_t n = 0; n < num_encoders; n++) { | |
597 EXPECT_EQ(0, acm_b_->Codec(n, &opus_codec_param)); | |
598 if (!strcmp(opus_codec_param.plname, "opus")) { | |
599 opus_codec_param.channels = 1; | |
600 EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param)); | |
601 break; | |
602 } | |
603 } | |
604 Run(channel_a2b_, audio_channels, codec_channels); | |
605 | |
606 // Encode in stereo, decode in mono. | |
607 RegisterSendCodec('A', codec_opus, 48000, 32000, 960, 2, opus_pltype_); | |
608 Run(channel_a2b_, audio_channels, codec_channels); | |
609 | |
610 out_file_.Close(); | |
611 | |
612 // Test switching between decoding mono and stereo for Opus. | |
613 | |
614 // Decode in mono. | |
615 test_cntr_++; | |
616 OpenOutFile(test_cntr_); | |
617 if (test_mode_ != 0) { | |
618 // Print out codec and settings | |
619 printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960" | |
620 " Decode: mono\n", test_cntr_); | |
621 } | |
622 Run(channel_a2b_, audio_channels, codec_channels); | |
623 out_file_.Close(); | |
624 // Decode in stereo. | |
625 test_cntr_++; | |
626 OpenOutFile(test_cntr_); | |
627 if (test_mode_ != 0) { | |
628 // Print out codec and settings | |
629 printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960" | |
630 " Decode: stereo\n", test_cntr_); | |
631 } | |
632 opus_codec_param.channels = 2; | |
633 EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param)); | |
634 Run(channel_a2b_, audio_channels, 2); | |
635 out_file_.Close(); | |
636 // Decode in mono. | |
637 test_cntr_++; | |
638 OpenOutFile(test_cntr_); | |
639 if (test_mode_ != 0) { | |
640 // Print out codec and settings | |
641 printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960" | |
642 " Decode: mono\n", test_cntr_); | |
643 } | |
644 opus_codec_param.channels = 1; | |
645 EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param)); | |
646 Run(channel_a2b_, audio_channels, codec_channels); | |
647 out_file_.Close(); | |
648 | |
649 #endif | |
650 | |
651 // Print out which codecs were tested, and which were not, in the run. | |
652 if (test_mode_ != 0) { | |
653 printf("\nThe following codecs was INCLUDED in the test:\n"); | |
654 #ifdef WEBRTC_CODEC_G722 | |
655 printf(" G.722\n"); | |
656 #endif | |
657 printf(" PCM16\n"); | |
658 printf(" G.711\n"); | |
659 #ifdef WEBRTC_CODEC_OPUS | |
660 printf(" Opus\n"); | |
661 #endif | |
662 printf("\nTo complete the test, listen to the %d number of output " | |
663 "files.\n", | |
664 test_cntr_); | |
665 } | |
666 | |
667 // Delete the file pointers. | |
668 delete in_file_stereo_; | |
669 delete in_file_mono_; | |
670 } | |
671 | |
672 // Register Codec to use in the test | |
673 // | |
674 // Input: side - which ACM to use, 'A' or 'B' | |
675 // codec_name - name to use when register the codec | |
676 // sampling_freq_hz - sampling frequency in Herz | |
677 // rate - bitrate in bytes | |
678 // pack_size - packet size in samples | |
679 // channels - number of channels; 1 for mono, 2 for stereo | |
680 // payload_type - payload type for the codec | |
681 void TestStereo::RegisterSendCodec(char side, char* codec_name, | |
682 int32_t sampling_freq_hz, int rate, | |
683 int pack_size, int channels, | |
684 int payload_type) { | |
685 if (test_mode_ != 0) { | |
686 // Print out codec and settings | |
687 printf("Codec: %s Freq: %d Rate: %d PackSize: %d\n", codec_name, | |
688 sampling_freq_hz, rate, pack_size); | |
689 } | |
690 | |
691 // Store packet size in samples, used to validate the received packet | |
692 pack_size_samp_ = pack_size; | |
693 | |
694 // Store the expected packet size in bytes, used to validate the received | |
695 // packet. Add 0.875 to always round up to a whole byte. | |
696 pack_size_bytes_ = (uint16_t)(static_cast<float>(pack_size * rate) / | |
697 static_cast<float>(sampling_freq_hz * 8) + | |
698 0.875); | |
699 | |
700 // Set pointer to the ACM where to register the codec | |
701 AudioCodingModule* my_acm = NULL; | |
702 switch (side) { | |
703 case 'A': { | |
704 my_acm = acm_a_.get(); | |
705 break; | |
706 } | |
707 case 'B': { | |
708 my_acm = acm_b_.get(); | |
709 break; | |
710 } | |
711 default: | |
712 break; | |
713 } | |
714 ASSERT_TRUE(my_acm != NULL); | |
715 | |
716 CodecInst my_codec_param; | |
717 // Get all codec parameters before registering | |
718 EXPECT_GT(AudioCodingModule::Codec(codec_name, &my_codec_param, | |
719 sampling_freq_hz, channels), -1); | |
720 my_codec_param.rate = rate; | |
721 my_codec_param.pacsize = pack_size; | |
722 EXPECT_EQ(0, my_acm->RegisterSendCodec(my_codec_param)); | |
723 | |
724 send_codec_name_ = codec_name; | |
725 } | |
726 | |
727 void TestStereo::Run(TestPackStereo* channel, int in_channels, int out_channels, | |
728 int percent_loss) { | |
729 AudioFrame audio_frame; | |
730 | |
731 int32_t out_freq_hz_b = out_file_.SamplingFrequency(); | |
732 uint16_t rec_size; | |
733 uint32_t time_stamp_diff; | |
734 channel->reset_payload_size(); | |
735 int error_count = 0; | |
736 int variable_bytes = 0; | |
737 int variable_packets = 0; | |
738 | |
739 while (1) { | |
740 // Simulate packet loss by setting |packet_loss_| to "true" in | |
741 // |percent_loss| percent of the loops. | |
742 if (percent_loss > 0) { | |
743 if (counter_ == floor((100 / percent_loss) + 0.5)) { | |
744 counter_ = 0; | |
745 channel->set_lost_packet(true); | |
746 } else { | |
747 channel->set_lost_packet(false); | |
748 } | |
749 counter_++; | |
750 } | |
751 | |
752 // Add 10 msec to ACM | |
753 if (in_channels == 1) { | |
754 if (in_file_mono_->EndOfFile()) { | |
755 break; | |
756 } | |
757 in_file_mono_->Read10MsData(audio_frame); | |
758 } else { | |
759 if (in_file_stereo_->EndOfFile()) { | |
760 break; | |
761 } | |
762 in_file_stereo_->Read10MsData(audio_frame); | |
763 } | |
764 EXPECT_GE(acm_a_->Add10MsData(audio_frame), 0); | |
765 | |
766 // Verify that the received packet size matches the settings. | |
767 rec_size = channel->payload_size(); | |
768 if ((0 < rec_size) & (rec_size < 65535)) { | |
769 if (strcmp(send_codec_name_, "opus") == 0) { | |
770 // Opus is a variable rate codec, hence calculate the average packet | |
771 // size, and later make sure the average is in the right range. | |
772 variable_bytes += rec_size; | |
773 variable_packets++; | |
774 } else { | |
775 // For fixed rate codecs, check that packet size is correct. | |
776 if ((rec_size != pack_size_bytes_ * out_channels) | |
777 && (pack_size_bytes_ < 65535)) { | |
778 error_count++; | |
779 } | |
780 } | |
781 // Verify that the timestamp is updated with expected length | |
782 time_stamp_diff = channel->timestamp_diff(); | |
783 if ((counter_ > 10) && (time_stamp_diff != pack_size_samp_)) { | |
784 error_count++; | |
785 } | |
786 } | |
787 | |
788 // Run received side of ACM | |
789 EXPECT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame)); | |
790 | |
791 // Write output speech to file | |
792 out_file_.Write10MsData( | |
793 audio_frame.data_, | |
794 audio_frame.samples_per_channel_ * audio_frame.num_channels_); | |
795 } | |
796 | |
797 EXPECT_EQ(0, error_count); | |
798 | |
799 // Check that packet size is in the right range for variable rate codecs, | |
800 // such as Opus. | |
801 if (variable_packets > 0) { | |
802 variable_bytes /= variable_packets; | |
803 EXPECT_NEAR(variable_bytes, pack_size_bytes_, 3); | |
804 } | |
805 | |
806 if (in_file_mono_->EndOfFile()) { | |
807 in_file_mono_->Rewind(); | |
808 } | |
809 if (in_file_stereo_->EndOfFile()) { | |
810 in_file_stereo_->Rewind(); | |
811 } | |
812 // Reset in case we ended with a lost packet | |
813 channel->set_lost_packet(false); | |
814 } | |
815 | |
816 void TestStereo::OpenOutFile(int16_t test_number) { | |
817 std::string file_name; | |
818 std::stringstream file_stream; | |
819 file_stream << webrtc::test::OutputPath() << "teststereo_out_" << test_number | |
820 << ".pcm"; | |
821 file_name = file_stream.str(); | |
822 out_file_.Open(file_name, 32000, "wb"); | |
823 } | |
824 | |
825 void TestStereo::DisplaySendReceiveCodec() { | |
826 auto send_codec = acm_a_->SendCodec(); | |
827 if (test_mode_ != 0) { | |
828 ASSERT_TRUE(send_codec); | |
829 printf("%s -> ", send_codec->plname); | |
830 } | |
831 CodecInst receive_codec; | |
832 acm_b_->ReceiveCodec(&receive_codec); | |
833 if (test_mode_ != 0) { | |
834 printf("%s\n", receive_codec.plname); | |
835 } | |
836 } | |
837 | |
838 } // namespace webrtc | |
OLD | NEW |