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