Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2013 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/interface/audio_coding_module.h"
     12 
     13 #include <assert.h>
     14 #include <math.h>
     15 
     16 #include <iostream>
     17 
     18 #include "gtest/gtest.h"
     19 #include "webrtc/common_types.h"
     20 #include "webrtc/engine_configurations.h"
     21 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
     22 #include "webrtc/modules/audio_coding/main/test/Channel.h"
     23 #include "webrtc/modules/audio_coding/main/test/PCMFile.h"
     24 #include "webrtc/modules/audio_coding/main/test/utility.h"
     25 #include "webrtc/system_wrappers/interface/event_wrapper.h"
     26 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     27 #include "webrtc/test/testsupport/fileutils.h"
     28 #include "webrtc/test/testsupport/gtest_disable.h"
     29 
     30 namespace webrtc {
     31 
     32 namespace {
     33 
     34 double FrameRms(AudioFrame& frame) {
     35   int samples = frame.num_channels_ * frame.samples_per_channel_;
     36   double rms = 0;
     37   for (int n = 0; n < samples; ++n)
     38     rms += frame.data_[n] * frame.data_[n];
     39   rms /= samples;
     40   rms = sqrt(rms);
     41   return rms;
     42 }
     43 
     44 }
     45 
     46 class InitialPlayoutDelayTest : public ::testing::Test {
     47  protected:
     48   InitialPlayoutDelayTest()
     49       : acm_a_(AudioCodingModule::Create(0)),
     50         acm_b_(AudioCodingModule::Create(1)),
     51         channel_a2b_(NULL) {}
     52 
     53   ~InitialPlayoutDelayTest() {
     54     if (channel_a2b_ != NULL) {
     55       delete channel_a2b_;
     56       channel_a2b_ = NULL;
     57     }
     58   }
     59 
     60   void SetUp() {
     61     ASSERT_TRUE(acm_a_.get() != NULL);
     62     ASSERT_TRUE(acm_b_.get() != NULL);
     63 
     64     EXPECT_EQ(0, acm_b_->InitializeReceiver());
     65     EXPECT_EQ(0, acm_a_->InitializeReceiver());
     66 
     67     // Register all L16 codecs in receiver.
     68     CodecInst codec;
     69     const int kFsHz[3] = { 8000, 16000, 32000 };
     70     const int kChannels[2] = { 1, 2 };
     71     for (int n = 0; n < 3; ++n) {
     72       for (int k = 0; k < 2; ++k) {
     73         AudioCodingModule::Codec("L16", &codec, kFsHz[n], kChannels[k]);
     74         acm_b_->RegisterReceiveCodec(codec);
     75       }
     76     }
     77 
     78     // Create and connect the channel
     79     channel_a2b_ = new Channel;
     80     acm_a_->RegisterTransportCallback(channel_a2b_);
     81     channel_a2b_->RegisterReceiverACM(acm_b_.get());
     82   }
     83 
     84   void NbMono() {
     85     CodecInst codec;
     86     AudioCodingModule::Codec("L16", &codec, 8000, 1);
     87     codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
     88     Run(codec, 1000);
     89   }
     90 
     91   void WbMono() {
     92     CodecInst codec;
     93     AudioCodingModule::Codec("L16", &codec, 16000, 1);
     94     codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
     95     Run(codec, 1000);
     96   }
     97 
     98   void SwbMono() {
     99     CodecInst codec;
    100     AudioCodingModule::Codec("L16", &codec, 32000, 1);
    101     codec.pacsize = codec.plfreq * 10 / 1000;  // 10 ms packets.
    102     Run(codec, 400);  // Memory constraints limit the buffer at <500 ms.
    103   }
    104 
    105   void NbStereo() {
    106     CodecInst codec;
    107     AudioCodingModule::Codec("L16", &codec, 8000, 2);
    108     codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
    109     Run(codec, 1000);
    110   }
    111 
    112   void WbStereo() {
    113     CodecInst codec;
    114     AudioCodingModule::Codec("L16", &codec, 16000, 2);
    115     codec.pacsize = codec.plfreq * 30 / 1000;  // 30 ms packets.
    116     Run(codec, 1000);
    117   }
    118 
    119   void SwbStereo() {
    120     CodecInst codec;
    121     AudioCodingModule::Codec("L16", &codec, 32000, 2);
    122     codec.pacsize = codec.plfreq * 10 / 1000;  // 10 ms packets.
    123     Run(codec, 400);  // Memory constraints limit the buffer at <500 ms.
    124   }
    125 
    126  private:
    127   void Run(CodecInst codec, int initial_delay_ms) {
    128     AudioFrame in_audio_frame;
    129     AudioFrame out_audio_frame;
    130     int num_frames = 0;
    131     const int kAmp = 10000;
    132     in_audio_frame.sample_rate_hz_ = codec.plfreq;
    133     in_audio_frame.num_channels_ = codec.channels;
    134     in_audio_frame.samples_per_channel_ = codec.plfreq / 100;  // 10 ms.
    135     int samples = in_audio_frame.num_channels_ *
    136         in_audio_frame.samples_per_channel_;
    137     for (int n = 0; n < samples; ++n) {
    138       in_audio_frame.data_[n] = kAmp;
    139     }
    140 
    141     uint32_t timestamp = 0;
    142     double rms = 0;
    143     ASSERT_EQ(0, acm_a_->RegisterSendCodec(codec));
    144     acm_b_->SetInitialPlayoutDelay(initial_delay_ms);
    145     while (rms < kAmp / 2) {
    146       in_audio_frame.timestamp_ = timestamp;
    147       timestamp += in_audio_frame.samples_per_channel_;
    148       ASSERT_EQ(0, acm_a_->Add10MsData(in_audio_frame));
    149       ASSERT_LE(0, acm_a_->Process());
    150       ASSERT_EQ(0, acm_b_->PlayoutData10Ms(codec.plfreq, &out_audio_frame));
    151       rms = FrameRms(out_audio_frame);
    152       ++num_frames;
    153     }
    154 
    155     ASSERT_GE(num_frames * 10, initial_delay_ms);
    156     ASSERT_LE(num_frames * 10, initial_delay_ms + 100);
    157   }
    158 
    159   scoped_ptr<AudioCodingModule> acm_a_;
    160   scoped_ptr<AudioCodingModule> acm_b_;
    161   Channel* channel_a2b_;
    162 };
    163 
    164 TEST_F(InitialPlayoutDelayTest, NbMono) { NbMono(); }
    165 
    166 TEST_F(InitialPlayoutDelayTest, WbMono) { WbMono(); }
    167 
    168 TEST_F(InitialPlayoutDelayTest, SwbMono) { SwbMono(); }
    169 
    170 TEST_F(InitialPlayoutDelayTest, NbStereo) { NbStereo(); }
    171 
    172 TEST_F(InitialPlayoutDelayTest, WbStereo) { WbStereo(); }
    173 
    174 TEST_F(InitialPlayoutDelayTest, SwbStereo) { SwbStereo(); }
    175 
    176 }  // namespace webrtc
    177