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

Side by Side Diff: chrome/browser/copresence/chrome_whispernet_client_browsertest.cc

Issue 940123004: Convert audio samples in Whispernet. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: test fix. Created 5 years, 10 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/copresence/chrome_whispernet_client.h" 5 #include "chrome/browser/copresence/chrome_whispernet_client.h"
6 6
7 #include <cmath>
7 #include <cstdlib> 8 #include <cstdlib>
8 #include <string> 9 #include <string>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/macros.h" 12 #include "base/macros.h"
12 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
13 #include "base/run_loop.h" 14 #include "base/run_loop.h"
14 #include "base/stl_util.h" 15 #include "base/stl_util.h"
15 #include "chrome/browser/extensions/api/copresence/copresence_api.h" 16 #include "chrome/browser/extensions/api/copresence/copresence_api.h"
16 #include "chrome/browser/extensions/extension_browsertest.h" 17 #include "chrome/browser/extensions/extension_browsertest.h"
17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
19 #include "chrome/test/base/in_process_browser_test.h" 20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "components/audio_modem/public/audio_modem_types.h"
20 #include "components/audio_modem/public/whispernet_client.h" 22 #include "components/audio_modem/public/whispernet_client.h"
23 #include "media/audio/audio_manager.h"
24 #include "media/audio/audio_manager_base.h"
25 #include "media/audio/audio_parameters.h"
21 #include "media/base/audio_bus.h" 26 #include "media/base/audio_bus.h"
27 #include "media/base/audio_converter.h"
22 28
23 using audio_modem::WhispernetClient; 29 using audio_modem::WhispernetClient;
24 using audio_modem::AUDIBLE; 30 using audio_modem::AUDIBLE;
25 using audio_modem::INAUDIBLE; 31 using audio_modem::INAUDIBLE;
26 using audio_modem::TokenParameters; 32 using audio_modem::TokenParameters;
27 33
28 namespace { 34 namespace {
29 35
30 // TODO(rkc): Add more varied test input. 36 // TODO(rkc): Add more varied test input.
31 const char kSixZeros[] = "MDAwMDAw"; 37 const char kSixZeros[] = "MDAwMDAw";
(...skipping 20 matching lines...) Expand all
52 void GetTokenParamsForLengths(const size_t token_lengths[2], 58 void GetTokenParamsForLengths(const size_t token_lengths[2],
53 TokenParameters* params) { 59 TokenParameters* params) {
54 params[0].length = token_lengths[0]; 60 params[0].length = token_lengths[0];
55 params[1].length = token_lengths[1]; 61 params[1].length = token_lengths[1];
56 } 62 }
57 63
58 void IgnoreResult(bool success) {} 64 void IgnoreResult(bool success) {}
59 65
60 } // namespace 66 } // namespace
61 67
62 class ChromeWhispernetClientTest : public ExtensionBrowserTest { 68 class ChromeWhispernetClientTest : public ExtensionBrowserTest,
69 public media::AudioConverter::InputCallback {
63 protected: 70 protected:
64 ChromeWhispernetClientTest() 71 ChromeWhispernetClientTest()
65 : initialized_(false), expected_audible_(false) {} 72 : initialized_(false),
73 expected_audible_(false),
74 saved_samples_index_(0) {}
66 75
67 ~ChromeWhispernetClientTest() override {} 76 ~ChromeWhispernetClientTest() override {}
68 77
69 void InitializeWhispernet() { 78 void InitializeWhispernet() {
70 scoped_ptr<WhispernetClient> client( 79 scoped_ptr<WhispernetClient> client(
71 new ChromeWhispernetClient(browser()->profile())); 80 new ChromeWhispernetClient(browser()->profile()));
72 client->Initialize(base::Bind( 81 client->Initialize(base::Bind(
73 &ChromeWhispernetClientTest::InitCallback, base::Unretained(this))); 82 &ChromeWhispernetClientTest::InitCallback, base::Unretained(this)));
74 83
75 run_loop_.reset(new base::RunLoop()); 84 run_loop_.reset(new base::RunLoop());
76 run_loop_->Run(); 85 run_loop_->Run();
86 EXPECT_TRUE(initialized_);
87 }
77 88
78 EXPECT_TRUE(initialized_); 89 // This needs to be called before any of the decoder tests are run. We can't
90 // run this code in the constructor or the SetUp methods because the audio
91 // manager seems to get initialized only *after* ExtensionBrowserTest::SetUp
92 // has finished executing. Setting up a testing AudioMager causes the actual
93 // create happening later in the browser initialization to fail. The only way
94 // around this at the moment seems to be to have this method called from
95 // every test before they try to decode.
96 void SetupDecode() {
97 // We get default parameters here instead of the constructor since
98 // initializing Whispernet also creates our AudioManager. Initializing from
99 // the test instead causes issues.
100 default_params_ = media::AudioManager::Get()->GetInputStreamParameters(
101 media::AudioManagerBase::kDefaultDeviceId);
102
103 coder_params_ = media::AudioParameters(
104 default_params_.format(), audio_modem::kDefaultChannelLayout,
105 audio_modem::kDefaultSampleRate, audio_modem::kDefaultBitsPerSample,
106 default_params_.frames_per_buffer(),
107 media::AudioParameters::NO_EFFECTS);
108
109 converter_.reset(new media::AudioConverter(
110 coder_params_, default_params_,
111 default_params_.sample_rate() == coder_params_.sample_rate()));
112 converter_->AddInput(this);
79 } 113 }
80 114
81 void EncodeTokenAndSaveSamples(WhispernetClient* client, 115 void EncodeTokenAndSaveSamples(WhispernetClient* client,
82 bool audible, 116 bool audible,
83 const std::string& token) { 117 const std::string& token) {
84 run_loop_.reset(new base::RunLoop()); 118 run_loop_.reset(new base::RunLoop());
85 client->RegisterSamplesCallback( 119 client->RegisterSamplesCallback(
86 base::Bind(&ChromeWhispernetClientTest::SamplesCallback, 120 base::Bind(&ChromeWhispernetClientTest::SamplesCallback,
87 base::Unretained(this))); 121 base::Unretained(this)));
88 expected_token_ = token; 122 expected_token_ = token;
(...skipping 11 matching lines...) Expand all
100 const std::string& expected_token, 134 const std::string& expected_token,
101 const TokenParameters token_params[2]) { 135 const TokenParameters token_params[2]) {
102 run_loop_.reset(new base::RunLoop()); 136 run_loop_.reset(new base::RunLoop());
103 client->RegisterTokensCallback(base::Bind( 137 client->RegisterTokensCallback(base::Bind(
104 &ChromeWhispernetClientTest::TokensCallback, base::Unretained(this))); 138 &ChromeWhispernetClientTest::TokensCallback, base::Unretained(this)));
105 expected_token_ = expected_token; 139 expected_token_ = expected_token;
106 expected_audible_ = expect_audible; 140 expected_audible_ = expect_audible;
107 141
108 ASSERT_GT(saved_samples_->frames(), 0); 142 ASSERT_GT(saved_samples_->frames(), 0);
109 143
110 // Convert our single channel samples to two channel. Decode samples
111 // expects 2 channel data.
112 scoped_refptr<media::AudioBusRefCounted> samples_bus = 144 scoped_refptr<media::AudioBusRefCounted> samples_bus =
113 media::AudioBusRefCounted::Create(2, saved_samples_->frames()); 145 ConvertSavedSamplesToSystemParams();
114 memcpy(samples_bus->channel(0),
115 saved_samples_->channel(0),
116 sizeof(float) * saved_samples_->frames());
117 memcpy(samples_bus->channel(1),
118 saved_samples_->channel(0),
119 sizeof(float) * saved_samples_->frames());
120
121 client->DecodeSamples(expect_audible ? AUDIBLE : INAUDIBLE, 146 client->DecodeSamples(expect_audible ? AUDIBLE : INAUDIBLE,
122 AudioBusToString(samples_bus), 147 AudioBusToString(samples_bus), token_params);
123 token_params);
124 run_loop_->Run(); 148 run_loop_->Run();
125 } 149 }
126 150
127 void InitCallback(bool success) { 151 void InitCallback(bool success) {
128 EXPECT_TRUE(success); 152 EXPECT_TRUE(success);
129 initialized_ = true; 153 initialized_ = true;
130 ASSERT_TRUE(run_loop_); 154 ASSERT_TRUE(run_loop_);
131 run_loop_->Quit(); 155 run_loop_->Quit();
132 } 156 }
133 157
134 void SamplesCallback( 158 void SamplesCallback(
135 audio_modem::AudioType type, 159 audio_modem::AudioType type,
136 const std::string& token, 160 const std::string& token,
137 const scoped_refptr<media::AudioBusRefCounted>& samples) { 161 const scoped_refptr<media::AudioBusRefCounted>& samples) {
138 EXPECT_EQ(expected_token_, token); 162 EXPECT_EQ(expected_token_, token);
139 EXPECT_EQ(expected_audible_, type == AUDIBLE); 163 EXPECT_EQ(expected_audible_, type == AUDIBLE);
140 saved_samples_ = samples; 164 saved_samples_ = samples;
141 ASSERT_TRUE(run_loop_); 165 ASSERT_TRUE(run_loop_);
142 run_loop_->Quit(); 166 run_loop_->Quit();
143 } 167 }
144 168
145 void TokensCallback(const std::vector<audio_modem::AudioToken>& tokens) { 169 void TokensCallback(const std::vector<audio_modem::AudioToken>& tokens) {
146 ASSERT_TRUE(run_loop_); 170 ASSERT_TRUE(run_loop_);
147 run_loop_->Quit(); 171 run_loop_->Quit();
148 172
149 EXPECT_EQ(expected_token_, tokens[0].token); 173 EXPECT_EQ(expected_token_, tokens[0].token);
150 EXPECT_EQ(expected_audible_, tokens[0].audible); 174 EXPECT_EQ(expected_audible_, tokens[0].audible);
151 } 175 }
152 176
177 private:
178 scoped_refptr<media::AudioBusRefCounted> ConvertSavedSamplesToSystemParams() {
179 int new_size =
180 saved_samples_->frames() *
181 std::ceil(static_cast<double>(default_params_.sample_rate()) /
182 coder_params_.sample_rate());
183 new_size =
184 std::ceil(static_cast<double>(new_size) / converter_->ChunkSize()) *
185 converter_->ChunkSize();
186
187 scoped_refptr<media::AudioBusRefCounted> converted_samples =
188 media::AudioBusRefCounted::Create(default_params_.channels(), new_size);
189
190 // Convert our single channel samples to two channel. Decode samples
191 // expects 2 channel data.
192 saved_samples_stereo_ =
193 media::AudioBusRefCounted::Create(2, saved_samples_->frames());
194 memcpy(saved_samples_stereo_->channel(0), saved_samples_->channel(0),
195 sizeof(float) * saved_samples_->frames());
196 memcpy(saved_samples_stereo_->channel(1), saved_samples_->channel(0),
197 sizeof(float) * saved_samples_->frames());
198
199 saved_samples_index_ = 0;
200 converter_->Convert(converted_samples.get());
201
202 return converted_samples;
203 }
204
205 // AudioConverter::InputCallback overrides:
206 double ProvideInput(media::AudioBus* dest,
207 base::TimeDelta /* buffer_delay */) override {
208 int remaining_frames = saved_samples_->frames() - saved_samples_index_;
209 int frames_to_copy = std::min(remaining_frames, dest->frames());
210 saved_samples_stereo_->CopyPartialFramesTo(saved_samples_index_,
211 frames_to_copy, 0, dest);
212 saved_samples_index_ += frames_to_copy;
213 return 1.0;
214 }
215
153 scoped_ptr<base::RunLoop> run_loop_; 216 scoped_ptr<base::RunLoop> run_loop_;
154 bool initialized_; 217 bool initialized_;
155 218
156 private:
157 std::string expected_token_; 219 std::string expected_token_;
158 bool expected_audible_; 220 bool expected_audible_;
221
159 scoped_refptr<media::AudioBusRefCounted> saved_samples_; 222 scoped_refptr<media::AudioBusRefCounted> saved_samples_;
223 scoped_refptr<media::AudioBusRefCounted> saved_samples_stereo_;
224 int saved_samples_index_;
225
226 scoped_ptr<media::AudioConverter> converter_;
227
228 media::AudioParameters default_params_;
229 media::AudioParameters coder_params_;
160 230
161 DISALLOW_COPY_AND_ASSIGN(ChromeWhispernetClientTest); 231 DISALLOW_COPY_AND_ASSIGN(ChromeWhispernetClientTest);
162 }; 232 };
163 233
164 // These tests are irrelevant if NACL is disabled. See crbug.com/449198 234 // These tests are irrelevant if NACL is disabled. See crbug.com/449198
165 #if defined(DISABLE_NACL) 235 #if defined(DISABLE_NACL)
166 #define MAYBE_Initialize DISABLED_Initialize 236 #define MAYBE_Initialize DISABLED_Initialize
167 #define MAYBE_EncodeAndDecode DISABLED_EncodeAndDecode 237 #define MAYBE_EncodeAndDecode DISABLED_EncodeAndDecode
168 #define MAYBE_TokenLengths DISABLED_TokenLengths 238 #define MAYBE_TokenLengths DISABLED_TokenLengths
169 #define MAYBE_MultipleClients DISABLED_MultipleClients 239 #define MAYBE_MultipleClients DISABLED_MultipleClients
170 #else 240 #else
171 #define MAYBE_Initialize Initialize 241 #define MAYBE_Initialize Initialize
172 #define MAYBE_EncodeAndDecode EncodeAndDecode 242 #define MAYBE_EncodeAndDecode EncodeAndDecode
173 #define MAYBE_TokenLengths TokenLengths 243 #define MAYBE_TokenLengths TokenLengths
174 #define MAYBE_MultipleClients MultipleClients 244 #define MAYBE_MultipleClients MultipleClients
175 #endif 245 #endif
176 246
177 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_Initialize) { 247 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_Initialize) {
178 InitializeWhispernet(); 248 InitializeWhispernet();
179 } 249 }
180 250
181 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_EncodeAndDecode) { 251 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_EncodeAndDecode) {
182 scoped_ptr<WhispernetClient> client( 252 scoped_ptr<WhispernetClient> client(
183 new ChromeWhispernetClient(browser()->profile())); 253 new ChromeWhispernetClient(browser()->profile()));
184 client->Initialize(base::Bind(&IgnoreResult)); 254 client->Initialize(base::Bind(&IgnoreResult));
185 255
186 TokenParameters token_params[2]; 256 TokenParameters token_params[2];
187 GetTokenParamsForLengths(kTokenLengths, token_params); 257 GetTokenParamsForLengths(kTokenLengths, token_params);
188 258
259 SetupDecode();
260
189 EncodeTokenAndSaveSamples(client.get(), true, kSixZeros); 261 EncodeTokenAndSaveSamples(client.get(), true, kSixZeros);
190 DecodeSamplesAndVerifyToken(client.get(), true, kSixZeros, token_params); 262 DecodeSamplesAndVerifyToken(client.get(), true, kSixZeros, token_params);
191 263
192 EncodeTokenAndSaveSamples(client.get(), false, kSixZeros); 264 EncodeTokenAndSaveSamples(client.get(), false, kSixZeros);
193 DecodeSamplesAndVerifyToken(client.get(), false, kSixZeros, token_params); 265 DecodeSamplesAndVerifyToken(client.get(), false, kSixZeros, token_params);
194 } 266 }
195 267
196 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_TokenLengths) { 268 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_TokenLengths) {
197 scoped_ptr<WhispernetClient> client( 269 scoped_ptr<WhispernetClient> client(
198 new ChromeWhispernetClient(browser()->profile())); 270 new ChromeWhispernetClient(browser()->profile()));
199 client->Initialize(base::Bind(&IgnoreResult)); 271 client->Initialize(base::Bind(&IgnoreResult));
200 272
201 const size_t kLongTokenLengths[2] = {8, 9}; 273 const size_t kLongTokenLengths[2] = {8, 9};
202 TokenParameters token_params[2]; 274 TokenParameters token_params[2];
203 GetTokenParamsForLengths(kLongTokenLengths, token_params); 275 GetTokenParamsForLengths(kLongTokenLengths, token_params);
276
277 SetupDecode();
278
204 EncodeTokenAndSaveSamples(client.get(), true, kEightZeros); 279 EncodeTokenAndSaveSamples(client.get(), true, kEightZeros);
205 DecodeSamplesAndVerifyToken(client.get(), true, kEightZeros, token_params); 280 DecodeSamplesAndVerifyToken(client.get(), true, kEightZeros, token_params);
206 281
207 EncodeTokenAndSaveSamples(client.get(), false, kNineZeros); 282 EncodeTokenAndSaveSamples(client.get(), false, kNineZeros);
208 DecodeSamplesAndVerifyToken(client.get(), false, kNineZeros, token_params); 283 DecodeSamplesAndVerifyToken(client.get(), false, kNineZeros, token_params);
209 } 284 }
210 285
211 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_MultipleClients) { 286 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_MultipleClients) {
212 scoped_ptr<WhispernetClient> client_1( 287 scoped_ptr<WhispernetClient> client_1(
213 new ChromeWhispernetClient(browser()->profile())); 288 new ChromeWhispernetClient(browser()->profile()));
214 scoped_ptr<WhispernetClient> client_2( 289 scoped_ptr<WhispernetClient> client_2(
215 new ChromeWhispernetClient(browser()->profile())); 290 new ChromeWhispernetClient(browser()->profile()));
216 291
217 TokenParameters token_params[2]; 292 TokenParameters token_params[2];
218 GetTokenParamsForLengths(kTokenLengths, token_params); 293 GetTokenParamsForLengths(kTokenLengths, token_params);
219 294
295 SetupDecode();
296
220 client_1->Initialize(base::Bind(&IgnoreResult)); 297 client_1->Initialize(base::Bind(&IgnoreResult));
221 298
222 EncodeTokenAndSaveSamples(client_1.get(), true, kSixZeros); 299 EncodeTokenAndSaveSamples(client_1.get(), true, kSixZeros);
223 DecodeSamplesAndVerifyToken(client_1.get(), true, kSixZeros, token_params); 300 DecodeSamplesAndVerifyToken(client_1.get(), true, kSixZeros, token_params);
224 301
225 client_2->Initialize(base::Bind(&IgnoreResult)); 302 client_2->Initialize(base::Bind(&IgnoreResult));
226 303
227 EncodeTokenAndSaveSamples(client_2.get(), true, kSixZeros); 304 EncodeTokenAndSaveSamples(client_2.get(), true, kSixZeros);
228 DecodeSamplesAndVerifyToken(client_2.get(), true, kSixZeros, token_params); 305 DecodeSamplesAndVerifyToken(client_2.get(), true, kSixZeros, token_params);
229 } 306 }
230 307
231 // TODO(ckehoe): Test crc and parity 308 // TODO(ckehoe): Test crc and parity
232 // TODO(ckehoe): More multi-client testing 309 // TODO(ckehoe): More multi-client testing
OLDNEW
« no previous file with comments | « chrome/browser/copresence/chrome_whispernet_client.cc ('k') | chrome/browser/copresence/chrome_whispernet_config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698