blob: 0bc94b743ca09614513d1c9c3e2ba6be56a46813 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
leozwang@webrtc.org91b359e2012-02-28 17:26:14 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000011#include "TwoWayCommunication.h"
12
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <ctype.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014#include <stdio.h>
15#include <string.h>
16
17#ifdef WIN32
18#include <Windows.h>
19#endif
20
niklase@google.com470e71d2011-07-07 08:21:25 +000021#include "common_types.h"
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000022#include "engine_configurations.h"
23#include "gtest/gtest.h"
24#include "PCMFile.h"
25#include "trace.h"
26#include "utility.h"
pbos@webrtc.org2ab209e2013-08-09 08:49:48 +000027#include "webrtc/test/testsupport/fileutils.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000028
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000029namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000030
31#define MAX_FILE_NAME_LENGTH_BYTE 500
32
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000033TwoWayCommunication::TwoWayCommunication(int testMode) {
34 _testMode = testMode;
niklase@google.com470e71d2011-07-07 08:21:25 +000035}
36
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000037TwoWayCommunication::~TwoWayCommunication() {
38 AudioCodingModule::Destroy(_acmA);
39 AudioCodingModule::Destroy(_acmB);
niklase@google.com470e71d2011-07-07 08:21:25 +000040
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000041 AudioCodingModule::Destroy(_acmRefA);
42 AudioCodingModule::Destroy(_acmRefB);
niklase@google.com470e71d2011-07-07 08:21:25 +000043
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000044 delete _channel_A2B;
45 delete _channel_B2A;
niklase@google.com470e71d2011-07-07 08:21:25 +000046
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000047 delete _channelRef_A2B;
48 delete _channelRef_B2A;
niklase@google.com470e71d2011-07-07 08:21:25 +000049#ifdef WEBRTC_DTMF_DETECTION
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000050 if(_dtmfDetectorA != NULL)
51 {
52 delete _dtmfDetectorA;
53 }
54 if(_dtmfDetectorB != NULL)
55 {
56 delete _dtmfDetectorB;
57 }
niklase@google.com470e71d2011-07-07 08:21:25 +000058#endif
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000059 _inFileA.Close();
60 _inFileB.Close();
61 _outFileA.Close();
62 _outFileB.Close();
63 _outFileRefA.Close();
64 _outFileRefB.Close();
niklase@google.com470e71d2011-07-07 08:21:25 +000065}
66
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000067uint8_t TwoWayCommunication::ChooseCodec(uint8_t* codecID_A,
68 uint8_t* codecID_B) {
69 AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
70 uint8_t noCodec = tmpACM->NumberOfCodecs();
71 CodecInst codecInst;
72 printf("List of Supported Codecs\n");
73 printf("========================\n");
74 for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) {
75 tmpACM->Codec(codecCntr, &codecInst);
76 printf("%d- %s\n", codecCntr, codecInst.plname);
77 }
78 printf("\nChoose a send codec for side A [0]: ");
79 char myStr[15] = "";
80 EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL);
81 *codecID_A = (uint8_t) atoi(myStr);
niklase@google.com470e71d2011-07-07 08:21:25 +000082
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000083 printf("\nChoose a send codec for side B [0]: ");
84 EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL);
85 *codecID_B = (uint8_t) atoi(myStr);
niklase@google.com470e71d2011-07-07 08:21:25 +000086
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000087 AudioCodingModule::Destroy(tmpACM);
88 printf("\n");
89 return 0;
90}
niklase@google.com470e71d2011-07-07 08:21:25 +000091
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000092int16_t TwoWayCommunication::SetUp() {
93 _acmA = AudioCodingModule::Create(1);
94 _acmB = AudioCodingModule::Create(2);
95
96 _acmRefA = AudioCodingModule::Create(3);
97 _acmRefB = AudioCodingModule::Create(4);
98
99 uint8_t codecID_A;
100 uint8_t codecID_B;
101
102 ChooseCodec(&codecID_A, &codecID_B);
103 CodecInst codecInst_A;
104 CodecInst codecInst_B;
105 CodecInst dummyCodec;
106 _acmA->Codec(codecID_A, &codecInst_A);
107 _acmB->Codec(codecID_B, &codecInst_B);
108
109 _acmA->Codec(6, &dummyCodec);
110
111 //--- Set A codecs
112 CHECK_ERROR(_acmA->RegisterSendCodec(codecInst_A));
113 CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
114#ifdef WEBRTC_DTMF_DETECTION
115 _dtmfDetectorA = new(DTMFDetector);
116 CHECK_ERROR(_acmA->RegisterIncomingMessagesCallback(_dtmfDetectorA,
117 ACMUSA));
118#endif
119 //--- Set ref-A codecs
120 CHECK_ERROR(_acmRefA->RegisterSendCodec(codecInst_A));
121 CHECK_ERROR(_acmRefA->RegisterReceiveCodec(codecInst_B));
122
123 //--- Set B codecs
124 CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
125 CHECK_ERROR(_acmB->RegisterReceiveCodec(codecInst_A));
126#ifdef WEBRTC_DTMF_DETECTION
127 _dtmfDetectorB = new(DTMFDetector);
128 CHECK_ERROR(_acmB->RegisterIncomingMessagesCallback(_dtmfDetectorB,
129 ACMUSA));
130#endif
131
132 //--- Set ref-B codecs
133 CHECK_ERROR(_acmRefB->RegisterSendCodec(codecInst_B));
134 CHECK_ERROR(_acmRefB->RegisterReceiveCodec(codecInst_A));
135
136 uint16_t frequencyHz;
137
138 //--- Input A
139 std::string in_file_name = webrtc::test::ResourcePath(
140 "audio_coding/testfile32kHz", "pcm");
141 frequencyHz = 32000;
142 printf("Enter input file at side A [%s]: ", in_file_name.c_str());
143 PCMFile::ChooseFile(&in_file_name, 499, &frequencyHz);
144 _inFileA.Open(in_file_name, frequencyHz, "rb");
145
146 //--- Output A
147 std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm";
148 printf("Output file at side A: %s\n", out_file_a.c_str());
149 printf("Sampling frequency (in Hz) of the above file: %u\n", frequencyHz);
150 _outFileA.Open(out_file_a, frequencyHz, "wb");
151 std::string ref_file_name = webrtc::test::OutputPath() + "ref_outA.pcm";
152 _outFileRefA.Open(ref_file_name, frequencyHz, "wb");
153
154 //--- Input B
155 in_file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz",
156 "pcm");
157 frequencyHz = 32000;
158 printf("\n\nEnter input file at side B [%s]: ", in_file_name.c_str());
159 PCMFile::ChooseFile(&in_file_name, 499, &frequencyHz);
160 _inFileB.Open(in_file_name, frequencyHz, "rb");
161
162 //--- Output B
163 std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm";
164 printf("Output file at side B: %s\n", out_file_b.c_str());
165 printf("Sampling frequency (in Hz) of the above file: %u\n", frequencyHz);
166 _outFileB.Open(out_file_b, frequencyHz, "wb");
167 ref_file_name = webrtc::test::OutputPath() + "ref_outB.pcm";
168 _outFileRefB.Open(ref_file_name, frequencyHz, "wb");
169
170 //--- Set A-to-B channel
171 _channel_A2B = new Channel;
172 _acmA->RegisterTransportCallback(_channel_A2B);
173 _channel_A2B->RegisterReceiverACM(_acmB);
174 //--- Do the same for the reference
175 _channelRef_A2B = new Channel;
176 _acmRefA->RegisterTransportCallback(_channelRef_A2B);
177 _channelRef_A2B->RegisterReceiverACM(_acmRefB);
178
179 //--- Set B-to-A channel
180 _channel_B2A = new Channel;
181 _acmB->RegisterTransportCallback(_channel_B2A);
182 _channel_B2A->RegisterReceiverACM(_acmA);
183 //--- Do the same for reference
184 _channelRef_B2A = new Channel;
185 _acmRefB->RegisterTransportCallback(_channelRef_B2A);
186 _channelRef_B2A->RegisterReceiverACM(_acmRefA);
187
188 // The clicks will be more obvious when we
189 // are in FAX mode.
190 _acmB->SetPlayoutMode(fax);
191 _acmRefB->SetPlayoutMode(fax);
192
193 return 0;
194}
195
196int16_t TwoWayCommunication::SetUpAutotest() {
197 _acmA = AudioCodingModule::Create(1);
198 _acmB = AudioCodingModule::Create(2);
199
200 _acmRefA = AudioCodingModule::Create(3);
201 _acmRefB = AudioCodingModule::Create(4);
202
203 CodecInst codecInst_A;
204 CodecInst codecInst_B;
205 CodecInst dummyCodec;
206
207 _acmA->Codec("ISAC", &codecInst_A, 16000, 1);
208 _acmB->Codec("L16", &codecInst_B, 8000, 1);
209 _acmA->Codec(6, &dummyCodec);
210
211 //--- Set A codecs
212 CHECK_ERROR(_acmA->RegisterSendCodec(codecInst_A));
213 CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
214#ifdef WEBRTC_DTMF_DETECTION
215 _dtmfDetectorA = new(DTMFDetector);
216 CHECK_ERROR(_acmA->RegisterIncomingMessagesCallback(_dtmfDetectorA,
217 ACMUSA));
218#endif
219
220 //--- Set ref-A codecs
221 CHECK_ERROR(_acmRefA->RegisterSendCodec(codecInst_A));
222 CHECK_ERROR(_acmRefA->RegisterReceiveCodec(codecInst_B));
223
224 //--- Set B codecs
225 CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
226 CHECK_ERROR(_acmB->RegisterReceiveCodec(codecInst_A));
227#ifdef WEBRTC_DTMF_DETECTION
228 _dtmfDetectorB = new(DTMFDetector);
229 CHECK_ERROR(_acmB->RegisterIncomingMessagesCallback(_dtmfDetectorB,
230 ACMUSA));
231#endif
232
233 //--- Set ref-B codecs
234 CHECK_ERROR(_acmRefB->RegisterSendCodec(codecInst_B));
235 CHECK_ERROR(_acmRefB->RegisterReceiveCodec(codecInst_A));
236
237 uint16_t frequencyHz;
238
239 //--- Input A and B
240 std::string in_file_name = webrtc::test::ResourcePath(
241 "audio_coding/testfile32kHz", "pcm");
242 frequencyHz = 16000;
243 _inFileA.Open(in_file_name, frequencyHz, "rb");
244 _inFileB.Open(in_file_name, frequencyHz, "rb");
245
246 //--- Output A
247 std::string output_file_a = webrtc::test::OutputPath() + "outAutotestA.pcm";
248 frequencyHz = 16000;
249 _outFileA.Open(output_file_a, frequencyHz, "wb");
250 std::string output_ref_file_a = webrtc::test::OutputPath()
251 + "ref_outAutotestA.pcm";
252 _outFileRefA.Open(output_ref_file_a, frequencyHz, "wb");
253
254 //--- Output B
255 std::string output_file_b = webrtc::test::OutputPath() + "outAutotestB.pcm";
256 frequencyHz = 16000;
257 _outFileB.Open(output_file_b, frequencyHz, "wb");
258 std::string output_ref_file_b = webrtc::test::OutputPath()
259 + "ref_outAutotestB.pcm";
260 _outFileRefB.Open(output_ref_file_b, frequencyHz, "wb");
261
262 //--- Set A-to-B channel
263 _channel_A2B = new Channel;
264 _acmA->RegisterTransportCallback(_channel_A2B);
265 _channel_A2B->RegisterReceiverACM(_acmB);
266 //--- Do the same for the reference
267 _channelRef_A2B = new Channel;
268 _acmRefA->RegisterTransportCallback(_channelRef_A2B);
269 _channelRef_A2B->RegisterReceiverACM(_acmRefB);
270
271 //--- Set B-to-A channel
272 _channel_B2A = new Channel;
273 _acmB->RegisterTransportCallback(_channel_B2A);
274 _channel_B2A->RegisterReceiverACM(_acmA);
275 //--- Do the same for reference
276 _channelRef_B2A = new Channel;
277 _acmRefB->RegisterTransportCallback(_channelRef_B2A);
278 _channelRef_B2A->RegisterReceiverACM(_acmRefA);
279
280 // The clicks will be more obvious when we
281 // are in FAX mode.
282 _acmB->SetPlayoutMode(fax);
283 _acmRefB->SetPlayoutMode(fax);
284
285 return 0;
286}
287
288void TwoWayCommunication::Perform() {
289 if (_testMode == 0) {
290 printf("Running TwoWayCommunication Test");
291 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
292 "---------- TwoWayCommunication ----------");
293 SetUpAutotest();
294 } else {
295 SetUp();
296 }
297 unsigned int msecPassed = 0;
298 unsigned int secPassed = 0;
299
300 int32_t outFreqHzA = _outFileA.SamplingFrequency();
301 int32_t outFreqHzB = _outFileB.SamplingFrequency();
302
303 AudioFrame audioFrame;
304
305 CodecInst codecInst_B;
306 CodecInst dummy;
307
308 _acmB->SendCodec(&codecInst_B);
309
310 if (_testMode != 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000311 printf("\n");
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000312 printf("sec:msec A B\n");
313 printf("-------- ----- -----\n");
314 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000315
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000316 while (!_inFileA.EndOfFile() && !_inFileB.EndOfFile()) {
317 _inFileA.Read10MsData(audioFrame);
318 _acmA->Add10MsData(audioFrame);
319 _acmRefA->Add10MsData(audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000320
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000321 _inFileB.Read10MsData(audioFrame);
322 _acmB->Add10MsData(audioFrame);
323 _acmRefB->Add10MsData(audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000324
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000325 _acmA->Process();
326 _acmB->Process();
327 _acmRefA->Process();
328 _acmRefB->Process();
niklase@google.com470e71d2011-07-07 08:21:25 +0000329
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000330 _acmA->PlayoutData10Ms(outFreqHzA, &audioFrame);
331 _outFileA.Write10MsData(audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000332
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000333 _acmRefA->PlayoutData10Ms(outFreqHzA, &audioFrame);
334 _outFileRefA.Write10MsData(audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000335
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000336 _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame);
337 _outFileB.Write10MsData(audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000338
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000339 _acmRefB->PlayoutData10Ms(outFreqHzB, &audioFrame);
340 _outFileRefB.Write10MsData(audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000341
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000342 msecPassed += 10;
343 if (msecPassed >= 1000) {
344 msecPassed = 0;
345 secPassed++;
346 }
347 if (((secPassed % 5) == 4) && (msecPassed == 0)) {
348 if (_testMode != 0) {
349 printf("%3u:%3u ", secPassed, msecPassed);
350 }
351 _acmA->ResetEncoder();
352 if (_testMode == 0) {
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +0000353 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000354 "---------- Errors expected");
355 printf(".");
356 } else {
357 printf("Reset Encoder (click in side B) ");
358 printf("Initialize Sender (no audio in side A)\n");
359 }
360 CHECK_ERROR(_acmB->InitializeSender());
niklase@google.com470e71d2011-07-07 08:21:25 +0000361 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000362 if (((secPassed % 5) == 4) && (msecPassed >= 990)) {
363 if (_testMode == 0) {
364 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
365 "----- END: Errors expected");
366 printf(".");
367 } else {
368 printf("%3u:%3u ", secPassed, msecPassed);
369 printf(" ");
370 printf("Register Send Codec (audio back in side A)\n");
371 }
372 CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
373 CHECK_ERROR(_acmB->SendCodec(&dummy));
niklase@google.com470e71d2011-07-07 08:21:25 +0000374 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000375 if (((secPassed % 7) == 6) && (msecPassed == 0)) {
376 CHECK_ERROR(_acmB->ResetDecoder());
377 if (_testMode == 0) {
378 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
379 "---------- Errors expected");
380 printf(".");
381 } else {
382 printf("%3u:%3u ", secPassed, msecPassed);
383 printf("Initialize Receiver (no audio in side A) ");
384 printf("Reset Decoder\n");
385 }
386 CHECK_ERROR(_acmA->InitializeReceiver());
niklase@google.com470e71d2011-07-07 08:21:25 +0000387 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000388 if (((secPassed % 7) == 6) && (msecPassed >= 990)) {
389 if (_testMode == 0) {
390 WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1,
391 "----- END: Errors expected");
392 printf(".");
393 } else {
394 printf("%3u:%3u ", secPassed, msecPassed);
395 printf("Register Receive Coded (audio back in side A)\n");
396 }
397 CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
niklase@google.com470e71d2011-07-07 08:21:25 +0000398 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000399 //Sleep(9);
400 }
401 if (_testMode == 0) {
402 printf("Done!\n");
403 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000404
405#ifdef WEBRTC_DTMF_DETECTION
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000406 printf("\nDTMF at Side A\n");
407 _dtmfDetectorA->PrintDetectedDigits();
niklase@google.com470e71d2011-07-07 08:21:25 +0000408
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000409 printf("\nDTMF at Side B\n");
410 _dtmfDetectorB->PrintDetectedDigits();
niklase@google.com470e71d2011-07-07 08:21:25 +0000411#endif
412
niklase@google.com470e71d2011-07-07 08:21:25 +0000413}
414
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000415} // namespace webrtc