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 "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/base/scoped_ptr.h"
20 #include "webrtc/common_types.h"
21 #include "webrtc/engine_configurations.h"
22 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
23 #include "webrtc/modules/audio_coding/main/test/Channel.h"
24 #include "webrtc/modules/audio_coding/main/test/PCMFile.h"
25 #include "webrtc/modules/audio_coding/main/test/utility.h"
26 #include "webrtc/system_wrappers/interface/event_wrapper.h"
27 #include "webrtc/test/testsupport/fileutils.h"
28 #include "webrtc/test/testsupport/gtest_disable.h"
29 
30 namespace webrtc {
31 
32 namespace {
33 
FrameRms(AudioFrame & frame)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:
InitialPlayoutDelayTest()48   InitialPlayoutDelayTest()
49       : acm_a_(AudioCodingModule::Create(0)),
50         acm_b_(AudioCodingModule::Create(1)),
51         channel_a2b_(NULL) {}
52 
~InitialPlayoutDelayTest()53   ~InitialPlayoutDelayTest() {
54     if (channel_a2b_ != NULL) {
55       delete channel_a2b_;
56       channel_a2b_ = NULL;
57     }
58   }
59 
SetUp()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 
NbMono()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 
WbMono()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 
SwbMono()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 
NbStereo()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 
WbStereo()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 
SwbStereo()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:
Run(CodecInst codec,int initial_delay_ms)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_GE(acm_a_->Add10MsData(in_audio_frame), 0);
149       ASSERT_EQ(0, acm_b_->PlayoutData10Ms(codec.plfreq, &out_audio_frame));
150       rms = FrameRms(out_audio_frame);
151       ++num_frames;
152     }
153 
154     ASSERT_GE(num_frames * 10, initial_delay_ms);
155     ASSERT_LE(num_frames * 10, initial_delay_ms + 100);
156   }
157 
158   rtc::scoped_ptr<AudioCodingModule> acm_a_;
159   rtc::scoped_ptr<AudioCodingModule> acm_b_;
160   Channel* channel_a2b_;
161 };
162 
TEST_F(InitialPlayoutDelayTest,NbMono)163 TEST_F(InitialPlayoutDelayTest, NbMono) { NbMono(); }
164 
TEST_F(InitialPlayoutDelayTest,WbMono)165 TEST_F(InitialPlayoutDelayTest, WbMono) { WbMono(); }
166 
TEST_F(InitialPlayoutDelayTest,SwbMono)167 TEST_F(InitialPlayoutDelayTest, SwbMono) { SwbMono(); }
168 
TEST_F(InitialPlayoutDelayTest,NbStereo)169 TEST_F(InitialPlayoutDelayTest, NbStereo) { NbStereo(); }
170 
TEST_F(InitialPlayoutDelayTest,WbStereo)171 TEST_F(InitialPlayoutDelayTest, WbStereo) { WbStereo(); }
172 
TEST_F(InitialPlayoutDelayTest,SwbStereo)173 TEST_F(InitialPlayoutDelayTest, SwbStereo) { SwbStereo(); }
174 
175 }  // namespace webrtc
176