16388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org/*
26388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
36388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *
46388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *  Use of this source code is governed by a BSD-style license
56388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *  that can be found in the LICENSE file in the root of the source
66388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *  tree. An additional intellectual property rights grant can be found
76388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *  in the file PATENTS.  All contributing project authors may
86388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
96388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org */
106388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1112dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <assert.h>
126388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include <math.h>
136388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
146388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include <iostream>
156388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
166388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "gflags/gflags.h"
1773222cff1a64cbc8eade9277cc63d516f7c20947tina.legrand@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
1800b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h"
197a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org#include "webrtc/common.h"
206388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/common_types.h"
216388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/engine_configurations.h"
223e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/include/audio_coding_module.h"
233e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h"
243e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h"
253e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/test/Channel.h"
263e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/test/PCMFile.h"
273e6db2321ccdc8738c9cecbe9bdab13d4f0f658dkjellander#include "webrtc/modules/audio_coding/test/utility.h"
2898f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/event_wrapper.h"
2973222cff1a64cbc8eade9277cc63d516f7c20947tina.legrand@webrtc.org#include "webrtc/test/testsupport/fileutils.h"
306388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
316388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgDEFINE_string(codec, "isac", "Codec Name");
326388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgDEFINE_int32(sample_rate_hz, 16000, "Sampling rate in Hertz.");
336388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgDEFINE_int32(num_channels, 1, "Number of Channels.");
346388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgDEFINE_string(input_file, "", "Input file, PCM16 32 kHz, optional.");
356388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgDEFINE_int32(delay, 0, "Delay in millisecond.");
366388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgDEFINE_bool(dtx, false, "Enable DTX at the sender side.");
377a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.orgDEFINE_bool(packet_loss, false, "Apply packet loss, c.f. Channel{.cc, .h}.");
387a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.orgDEFINE_bool(fec, false, "Use Forward Error Correction (FEC).");
396388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
406388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgnamespace webrtc {
417a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org
426388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgnamespace {
436388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
447a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.orgstruct CodecSettings {
456388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  char name[50];
466388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  int sample_rate_hz;
476388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  int num_channels;
486388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org};
496388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
507a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.orgstruct AcmSettings {
516388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  bool dtx;
526388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  bool fec;
536388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org};
546388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
557a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.orgstruct TestSettings {
567a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  CodecSettings codec;
577a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  AcmSettings acm;
586388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  bool packet_loss;
596388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org};
606388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
617a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org}  // namespace
626388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
636388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgclass DelayTest {
646388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org public:
65adaf80961280dfecd3fdcc23bd3fa0a312ce42dehenrik.lundin@webrtc.org  DelayTest()
66adaf80961280dfecd3fdcc23bd3fa0a312ce42dehenrik.lundin@webrtc.org      : acm_a_(AudioCodingModule::Create(0)),
67adaf80961280dfecd3fdcc23bd3fa0a312ce42dehenrik.lundin@webrtc.org        acm_b_(AudioCodingModule::Create(1)),
687a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org        channel_a2b_(new Channel),
69d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org        test_cntr_(0),
70d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org        encoding_sample_rate_hz_(8000) {}
716388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
727a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  ~DelayTest() {
73d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    if (channel_a2b_ != NULL) {
746388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      delete channel_a2b_;
756388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      channel_a2b_ = NULL;
766388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    }
777a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    in_file_a_.Close();
786388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
796388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
807a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  void Initialize() {
816388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    test_cntr_ = 0;
82d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    std::string file_name = webrtc::test::ResourcePath(
83d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org        "audio_coding/testfile32kHz", "pcm");
846388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    if (FLAGS_input_file.size() > 0)
856388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      file_name = FLAGS_input_file;
866388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    in_file_a_.Open(file_name, 32000, "rb");
877a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    ASSERT_EQ(0, acm_a_->InitializeReceiver()) <<
887a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org        "Couldn't initialize receiver.\n";
897a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    ASSERT_EQ(0, acm_b_->InitializeReceiver()) <<
907a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org        "Couldn't initialize receiver.\n";
916388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
926388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    if (FLAGS_delay > 0) {
937a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org      ASSERT_EQ(0, acm_b_->SetMinimumPlayoutDelay(FLAGS_delay)) <<
947a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org          "Failed to set minimum delay.\n";
956388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    }
966388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
977a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    int num_encoders = acm_a_->NumberOfCodecs();
986388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    CodecInst my_codec_param;
99d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    for (int n = 0; n < num_encoders; n++) {
1007a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org      EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)) <<
1017a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org          "Failed to get codec.";
1026388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      if (STR_CASE_CMP(my_codec_param.plname, "opus") == 0)
1036388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org        my_codec_param.channels = 1;
104d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      else if (my_codec_param.channels > 1)
1056388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org        continue;
1066388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      if (STR_CASE_CMP(my_codec_param.plname, "CN") == 0 &&
1076388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org          my_codec_param.plfreq == 48000)
108d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org        continue;
1096388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      if (STR_CASE_CMP(my_codec_param.plname, "telephone-event") == 0)
1106388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org        continue;
1117a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org      ASSERT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param)) <<
1127a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org          "Couldn't register receive codec.\n";
1136388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    }
1146388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1156388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    // Create and connect the channel
1167a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    ASSERT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_)) <<
1177a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org        "Couldn't register Transport callback.\n";
11889df0928071d156777aa82755e701755b4829576andrew@webrtc.org    channel_a2b_->RegisterReceiverACM(acm_b_.get());
1196388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1206388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1217a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  void Perform(const TestSettings* config, size_t num_tests, int duration_sec,
1226388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org               const char* output_prefix) {
1236388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    for (size_t n = 0; n < num_tests; ++n) {
1246388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      ApplyConfig(config[n]);
1256388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      Run(duration_sec, output_prefix);
1266388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    }
1276388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1286388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1296388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org private:
1307a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  void ApplyConfig(const TestSettings& config) {
1316388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    printf("====================================\n");
1326388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    printf("Test %d \n"
133d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           "Codec: %s, %d kHz, %d channel(s)\n"
134d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           "ACM: DTX %s, FEC %s\n"
135d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           "Channel: %s\n",
136d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           ++test_cntr_, config.codec.name, config.codec.sample_rate_hz,
137d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           config.codec.num_channels, config.acm.dtx ? "on" : "off",
138d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           config.acm.fec ? "on" : "off",
139d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org           config.packet_loss ? "with packet-loss" : "no packet-loss");
1406388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    SendCodec(config.codec);
1416388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    ConfigAcm(config.acm);
1426388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    ConfigChannel(config.packet_loss);
1436388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1446388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1457a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  void SendCodec(const CodecSettings& config) {
1466388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    CodecInst my_codec_param;
1477a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    ASSERT_EQ(0, AudioCodingModule::Codec(
1487a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org              config.name, &my_codec_param, config.sample_rate_hz,
1497a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org              config.num_channels)) << "Specified codec is not supported.\n";
1507a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org
1516388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    encoding_sample_rate_hz_ = my_codec_param.plfreq;
1527a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    ASSERT_EQ(0, acm_a_->RegisterSendCodec(my_codec_param)) <<
1537a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org        "Failed to register send-codec.\n";
1546388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1556388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1567a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  void ConfigAcm(const AcmSettings& config) {
1577a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    ASSERT_EQ(0, acm_a_->SetVAD(config.dtx, config.dtx, VADAggr)) <<
1587a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org        "Failed to set VAD.\n";
159aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org    ASSERT_EQ(0, acm_a_->SetREDStatus(config.fec)) <<
160aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org        "Failed to set RED.\n";
1616388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1626388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1636388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  void ConfigChannel(bool packet_loss) {
1646388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    channel_a2b_->SetFECTestWithPacketLoss(packet_loss);
1656388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1666388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1676388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  void OpenOutFile(const char* output_id) {
1686388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    std::stringstream file_stream;
169d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    file_stream << "delay_test_" << FLAGS_codec << "_" << FLAGS_sample_rate_hz
17074f0f3551ecd596dc0f83146d218887082528fa8henrik.lundin        << "Hz" << "_" << FLAGS_delay << "ms.pcm";
171d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    std::cout << "Output file: " << file_stream.str() << std::endl << std::endl;
1726388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    std::string file_name = webrtc::test::OutputPath() + file_stream.str();
1736388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    out_file_b_.Open(file_name.c_str(), 32000, "wb");
1746388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
1756388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1766388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  void Run(int duration_sec, const char* output_prefix) {
1776388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    OpenOutFile(output_prefix);
1786388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    AudioFrame audio_frame;
1796388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    uint32_t out_freq_hz_b = out_file_b_.SamplingFrequency();
1806388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1816388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    int num_frames = 0;
1826388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    int in_file_frames = 0;
1836388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    uint32_t playout_ts;
1846388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    uint32_t received_ts;
1856388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    double average_delay = 0;
1866388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    double inst_delay_sec = 0;
187d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    while (num_frames < (duration_sec * 100)) {
1886388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      if (in_file_a_.EndOfFile()) {
1896388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org        in_file_a_.Rewind();
1906388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      }
1916388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
1926388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      // Print delay information every 16 frame
1936388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      if ((num_frames & 0x3F) == 0x3F) {
194c0bd7be0df67735d63f5cdd302a3b85f88239874minyue@webrtc.org        NetworkStatistics statistics;
195c0bd7be0df67735d63f5cdd302a3b85f88239874minyue@webrtc.org        acm_b_->GetNetworkStatistics(&statistics);
1966388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org        fprintf(stdout, "delay: min=%3d  max=%3d  mean=%3d  median=%3d"
1976388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org                " ts-based average = %6.3f, "
1986388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org                "curr buff-lev = %4u opt buff-lev = %4u \n",
199d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                statistics.minWaitingTimeMs, statistics.maxWaitingTimeMs,
200d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                statistics.meanWaitingTimeMs, statistics.medianWaitingTimeMs,
201d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                average_delay, statistics.currentBufferSize,
2026388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org                statistics.preferredBufferSize);
203d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org        fflush (stdout);
2046388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      }
2056388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
2066388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      in_file_a_.Read10MsData(audio_frame);
207f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org      ASSERT_GE(acm_a_->Add10MsData(audio_frame), 0);
2087a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org      ASSERT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame));
209d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      out_file_b_.Write10MsData(
210d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org          audio_frame.data_,
211d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org          audio_frame.samples_per_channel_ * audio_frame.num_channels_);
2127a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org      acm_b_->PlayoutTimestamp(&playout_ts);
2136388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      received_ts = channel_a2b_->LastInTimestamp();
214d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      inst_delay_sec = static_cast<uint32_t>(received_ts - playout_ts)
215d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org          / static_cast<double>(encoding_sample_rate_hz_);
2166388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
2176388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      if (num_frames > 10)
2186388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org        average_delay = 0.95 * average_delay + 0.05 * inst_delay_sec;
2196388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
2206388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      ++num_frames;
2216388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org      ++in_file_frames;
2226388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    }
2236388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org    out_file_b_.Close();
2246388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  }
2256388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
22600b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org  rtc::scoped_ptr<AudioCodingModule> acm_a_;
22700b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org  rtc::scoped_ptr<AudioCodingModule> acm_b_;
2286388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
2296388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  Channel* channel_a2b_;
2306388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
2316388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  PCMFile in_file_a_;
2326388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  PCMFile out_file_b_;
2336388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  int test_cntr_;
2346388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org  int encoding_sample_rate_hz_;
2356388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org};
2366388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org
237185bae4b6fb8b78dbfc2cfbd8a5c2d71091f2233andresp@webrtc.org}  // namespace webrtc
2387a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org
2397a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.orgint main(int argc, char* argv[]) {
2407a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  google::ParseCommandLineFlags(&argc, &argv, true);
2417a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  webrtc::TestSettings test_setting;
2427a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  strcpy(test_setting.codec.name, FLAGS_codec.c_str());
2437a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org
2447a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  if (FLAGS_sample_rate_hz != 8000 &&
2457a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org      FLAGS_sample_rate_hz != 16000 &&
2467a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org      FLAGS_sample_rate_hz != 32000 &&
2477a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org      FLAGS_sample_rate_hz != 48000) {
2487a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    std::cout << "Invalid sampling rate.\n";
2497a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    return 1;
2507a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  }
2517a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  test_setting.codec.sample_rate_hz = FLAGS_sample_rate_hz;
2527a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  if (FLAGS_num_channels < 1 || FLAGS_num_channels > 2) {
2537a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    std::cout << "Only mono and stereo are supported.\n";
2547a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org    return 1;
2557a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  }
2567a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  test_setting.codec.num_channels = FLAGS_num_channels;
2577a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  test_setting.acm.dtx = FLAGS_dtx;
2587a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  test_setting.acm.fec = FLAGS_fec;
2597a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  test_setting.packet_loss = FLAGS_packet_loss;
2607a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org
261adaf80961280dfecd3fdcc23bd3fa0a312ce42dehenrik.lundin@webrtc.org  webrtc::DelayTest delay_test;
2627a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  delay_test.Initialize();
2637a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  delay_test.Perform(&test_setting, 1, 240, "delay_test");
2647a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org  return 0;
2657a05ae5c697370ef19cad72c5443071caa4867afturaj@webrtc.org}
266