Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: webrtc/modules/audio_coding/codecs/isac/unittest.cc

Issue 1208923002: iSAC: Functions for importing and exporting bandwidth est. info (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: unittest works now Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2015 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 <algorithm>
12 #include <sstream>
13 #include <vector>
14
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/buffer.h"
17 #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_is acfix.h"
18 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_i sac.h"
19 #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
20 #include "webrtc/test/testsupport/fileutils.h"
21
22 namespace webrtc {
23
24 namespace {
25
26 std::vector<int16_t> LoadSpeechData() {
27 webrtc::test::InputAudioFile input_file(
28 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"));
29 static const int kIsacNumberOfSamples = 32 * 60; // 60 ms at 32 kHz
30 std::vector<int16_t> speech_data(kIsacNumberOfSamples);
31 input_file.Read(kIsacNumberOfSamples, speech_data.data());
32 return speech_data;
33 }
34
35 template <typename T>
36 IsacBandwidthInfo GetBwInfo(typename T::instance_type* inst) {
37 IsacBandwidthInfo bi;
38 T::GetBandwidthInfo(inst, &bi);
39 EXPECT_TRUE(bi.in_use);
40 return bi;
41 }
42
43 template <typename T>
44 rtc::Buffer EncodePacket(typename T::instance_type* inst,
45 const IsacBandwidthInfo* bi,
46 const int16_t* speech_data,
47 int framesize_ms) {
48 rtc::Buffer output(1000);
49 for (int i = 0;; ++i) {
50 if (bi)
51 T::SetBandwidthInfo(inst, bi);
52 int encoded_bytes = T::Encode(inst, speech_data, output.data());
53 if (i + 1 == framesize_ms / 10) {
54 EXPECT_GT(encoded_bytes, 0);
55 EXPECT_LE(static_cast<size_t>(encoded_bytes), output.size());
56 output.SetSize(encoded_bytes);
57 return output;
58 }
59 EXPECT_EQ(0, encoded_bytes);
60 }
61 }
62
63 class BoundedCapacityChannel final {
64 public:
65 BoundedCapacityChannel(int rate_bps)
hlundin-webrtc 2015/07/02 14:04:36 Suggest you call the parameter rate_bits_per_secon
kwiberg-webrtc 2015/07/03 00:27:53 Done, for the whole file.
66 : current_time_rtp_(0),
67 channel_rate_bytes_per_sample_(rate_bps / (8.0 * kSamplesPerSecond)) {}
68
69 // Simulate sending the given number of bytes at the given RTP time. Returns
70 // the
hlundin-webrtc 2015/07/02 14:04:36 Re-flow the line breaks.
kwiberg-webrtc 2015/07/03 00:27:53 Done.
71 // new current RTP time after the sending is done.
72 int Send(int send_time_rtp, int nbytes) {
73 current_time_rtp_ = std::max(current_time_rtp_, send_time_rtp) +
74 nbytes / channel_rate_bytes_per_sample_;
75 return current_time_rtp_;
76 }
77
78 private:
79 int current_time_rtp_;
80 // The somewhat strange unit for channel rate, bytes per sample, is because
81 // RTP time is measured in samples:
82 const double channel_rate_bytes_per_sample_;
83 static const int kSamplesPerSecond = 16000;
84 };
85
86 template <typename T, bool adaptive>
87 struct TestParam {};
88
89 template <>
90 struct TestParam<IsacFloat, true> {
91 static const int time_to_settle = 200;
92 static int ExpectedRateBps(int rate_bps) { return rate_bps; }
93 };
94
95 template <>
96 struct TestParam<IsacFix, true> {
97 static const int time_to_settle = 350;
98 static int ExpectedRateBps(int rate_bps) {
99 // For some reason, IsacFix fails to adapt to the channel's actual
100 // bandwidth. Instead, it settles on a few hundred packets at 10kbit/s,
101 // then a few hundred at 5kbit/s, then a few hundred at 10kbit/s, and so
102 // on. The 200 packets starting at 350 are in the middle of the first
103 // 10kbit/s run.
104 return 10000;
105 }
106 };
107
108 template <>
109 struct TestParam<IsacFloat, false> {
110 static const int time_to_settle = 0;
111 static int ExpectedRateBps(int rate_bps) { return 16000; }
112 };
113
114 template <>
115 struct TestParam<IsacFix, false> {
116 static const int time_to_settle = 0;
117 static int ExpectedRateBps(int rate_bps) { return 8000; }
118 };
119
120 // Test that the iSAC encoder produces identical output whether or not we use a
121 // conjoined encoder+decoder pair or a separate encoder and decoder that
122 // communicate BW estimation info explicitly.
123 template <typename T, bool adaptive>
124 void TestGetSetBandwidthInfo(const int16_t* speech_data, int rate_bps) {
125 using Param = TestParam<T, adaptive>;
126
127 // Conjoined encoder/decoder pair:
128 typename T::instance_type* encdec;
129 ASSERT_EQ(0, T::Create(&encdec));
130 ASSERT_EQ(0, T::EncoderInit(encdec, adaptive ? 0 : 1));
131 ASSERT_EQ(0, T::DecoderInit(encdec));
132
133 // Disjoint encoder/decoder pair:
134 typename T::instance_type* enc;
135 ASSERT_EQ(0, T::Create(&enc));
136 ASSERT_EQ(0, T::EncoderInit(enc, adaptive ? 0 : 1));
137 typename T::instance_type* dec;
138 ASSERT_EQ(0, T::Create(&dec));
139 ASSERT_EQ(0, T::DecoderInit(dec));
140
141 // 0. Get initial BW info from decoder.
142 auto bi = GetBwInfo<T>(dec);
143
144 BoundedCapacityChannel channel1(rate_bps), channel2(rate_bps);
145 std::vector<size_t> packet_sizes;
146 for (int i = 0; i < Param::time_to_settle + 200; ++i) {
147 std::ostringstream ss;
148 ss << " i = " << i;
149 SCOPED_TRACE(ss.str());
150
151 // 1. Encode 6 * 10 ms (adaptive) or 3 * 10 ms (nonadaptive). The separate
152 // encoder is given the BW info before each encode call.
153 const int framesize_ms = adaptive ? 60 : 30;
154 auto bitstream1 =
155 EncodePacket<T>(encdec, nullptr, speech_data, framesize_ms);
156 auto bitstream2 = EncodePacket<T>(enc, &bi, speech_data, framesize_ms);
157 EXPECT_EQ(bitstream1, bitstream2);
158 if (i > Param::time_to_settle)
159 packet_sizes.push_back(bitstream1.size());
160
161 // 2. Deliver the encoded data to the decoders (but don't actually ask them
162 // to decode it; that's not necessary). Then get new BW info from the
163 // separate decoder.
164 const int samples_per_packet = 16 * framesize_ms;
165 const int send_time = i * samples_per_packet;
166 EXPECT_EQ(0, T::UpdateBwEstimate(
167 encdec, bitstream1.data(), bitstream1.size(), i, send_time,
168 channel1.Send(send_time, bitstream1.size())));
169 EXPECT_EQ(0, T::UpdateBwEstimate(
170 dec, bitstream2.data(), bitstream2.size(), i, send_time,
171 channel2.Send(send_time, bitstream2.size())));
172 bi = GetBwInfo<T>(dec);
173 }
174
175 EXPECT_EQ(0, T::Free(encdec));
176 EXPECT_EQ(0, T::Free(enc));
177 EXPECT_EQ(0, T::Free(dec));
178
179 // The average send bitrate is close to the channel's capacity.
180 double avg_size =
181 std::accumulate(packet_sizes.begin(), packet_sizes.end(), 0) /
182 static_cast<double>(packet_sizes.size());
183 double avg_rate_bps = 8.0 * avg_size / 60e-3;
hlundin-webrtc 2015/07/02 14:04:36 Shouldn't 60e-3 be 30e-3 in the non-adaptive case?
kwiberg-webrtc 2015/07/03 00:27:53 Yes. Done.
184 double expected_rate_bps = Param::ExpectedRateBps(rate_bps);
185 EXPECT_GT(avg_rate_bps / expected_rate_bps, 0.99);
186 EXPECT_LT(avg_rate_bps / expected_rate_bps, 1.06);
187
188 // The largest packet isn't that large, and the smallest not that small.
189 auto minmax_size =
190 std::minmax_element(packet_sizes.begin(), packet_sizes.end());
191 double size_range = *minmax_size.second - *minmax_size.first;
192 EXPECT_LE(size_range / avg_size, 0.16);
193 }
194
195 } // namespace
196
197 TEST(IsacCommonTest, GetSetBandwidthInfoFloat12kAdaptive) {
198 TestGetSetBandwidthInfo<IsacFloat, true>(LoadSpeechData().data(), 12000);
199 }
200
201 TEST(IsacCommonTest, GetSetBandwidthInfoFloat15kAdaptive) {
202 TestGetSetBandwidthInfo<IsacFloat, true>(LoadSpeechData().data(), 15000);
203 }
204
205 TEST(IsacCommonTest, GetSetBandwidthInfoFloat19kAdaptive) {
206 TestGetSetBandwidthInfo<IsacFloat, true>(LoadSpeechData().data(), 19000);
207 }
208
209 TEST(IsacCommonTest, GetSetBandwidthInfoFloat22kAdaptive) {
210 TestGetSetBandwidthInfo<IsacFloat, true>(LoadSpeechData().data(), 22000);
211 }
212
213 TEST(IsacCommonTest, GetSetBandwidthInfoFix12kAdaptive) {
214 TestGetSetBandwidthInfo<IsacFix, true>(LoadSpeechData().data(), 12000);
215 }
216
217 TEST(IsacCommonTest, GetSetBandwidthInfoFix15kAdaptive) {
218 TestGetSetBandwidthInfo<IsacFix, true>(LoadSpeechData().data(), 15000);
219 }
220
221 TEST(IsacCommonTest, GetSetBandwidthInfoFix19kAdaptive) {
222 TestGetSetBandwidthInfo<IsacFix, true>(LoadSpeechData().data(), 19000);
223 }
224
225 TEST(IsacCommonTest, GetSetBandwidthInfoFix22kAdaptive) {
226 TestGetSetBandwidthInfo<IsacFix, true>(LoadSpeechData().data(), 22000);
227 }
228
229 TEST(IsacCommonTest, GetSetBandwidthInfoFloat12k) {
230 TestGetSetBandwidthInfo<IsacFloat, false>(LoadSpeechData().data(), 12000);
231 }
232
233 TEST(IsacCommonTest, GetSetBandwidthInfoFloat15k) {
234 TestGetSetBandwidthInfo<IsacFloat, false>(LoadSpeechData().data(), 15000);
235 }
236
237 TEST(IsacCommonTest, GetSetBandwidthInfoFloat19k) {
238 TestGetSetBandwidthInfo<IsacFloat, false>(LoadSpeechData().data(), 19000);
239 }
240
241 TEST(IsacCommonTest, GetSetBandwidthInfoFloat22k) {
242 TestGetSetBandwidthInfo<IsacFloat, false>(LoadSpeechData().data(), 22000);
243 }
244
245 TEST(IsacCommonTest, GetSetBandwidthInfoFix12k) {
246 TestGetSetBandwidthInfo<IsacFix, false>(LoadSpeechData().data(), 12000);
247 }
248
249 TEST(IsacCommonTest, GetSetBandwidthInfoFix15k) {
250 TestGetSetBandwidthInfo<IsacFix, false>(LoadSpeechData().data(), 15000);
251 }
252
253 TEST(IsacCommonTest, GetSetBandwidthInfoFix19k) {
254 TestGetSetBandwidthInfo<IsacFix, false>(LoadSpeechData().data(), 19000);
255 }
256
257 TEST(IsacCommonTest, GetSetBandwidthInfoFix22k) {
258 TestGetSetBandwidthInfo<IsacFix, false>(LoadSpeechData().data(), 22000);
259 }
260
261 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/codecs/isac/main/source/structs.h ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698