OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "media/audio/audio_parameters.h" | |
6 #include "media/base/fake_audio_render_callback.h" | |
7 #include "media/base/mock_audio_renderer_sink.h" | |
8 #include "testing/gmock/include/gmock/gmock.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 #include "third_party/WebKit/public/web/WebAudioSourceProviderClient.h" | |
11 #include "webkit/renderer/media/webaudiosourceprovider_impl.h" | |
12 | |
13 namespace webkit_media { | |
14 | |
15 namespace { | |
16 const float kTestVolume = 0.25; | |
17 } // namespace | |
18 | |
19 class WebAudioSourceProviderImplTest | |
20 : public testing::Test, | |
21 public WebKit::WebAudioSourceProviderClient { | |
22 public: | |
23 WebAudioSourceProviderImplTest() | |
24 : params_(media::AudioParameters::AUDIO_PCM_LINEAR, | |
25 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 64), | |
26 fake_callback_(0.1), | |
27 mock_sink_(new media::MockAudioRendererSink()), | |
28 wasp_impl_(new WebAudioSourceProviderImpl(mock_sink_)) { | |
29 } | |
30 | |
31 virtual ~WebAudioSourceProviderImplTest() {} | |
32 | |
33 void CallAllSinkMethodsAndVerify(bool verify) { | |
34 testing::InSequence s; | |
35 | |
36 EXPECT_CALL(*mock_sink_.get(), Start()).Times(verify); | |
37 wasp_impl_->Start(); | |
38 | |
39 EXPECT_CALL(*mock_sink_.get(), Play()).Times(verify); | |
40 wasp_impl_->Play(); | |
41 | |
42 EXPECT_CALL(*mock_sink_.get(), Pause()).Times(verify); | |
43 wasp_impl_->Pause(); | |
44 | |
45 EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume)).Times(verify); | |
46 wasp_impl_->SetVolume(kTestVolume); | |
47 | |
48 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(verify); | |
49 wasp_impl_->Stop(); | |
50 | |
51 testing::Mock::VerifyAndClear(mock_sink_.get()); | |
52 } | |
53 | |
54 void SetClient(WebKit::WebAudioSourceProviderClient* client) { | |
55 testing::InSequence s; | |
56 | |
57 if (client) { | |
58 EXPECT_CALL(*mock_sink_.get(), Stop()); | |
59 EXPECT_CALL(*this, setFormat(params_.channels(), params_.sample_rate())); | |
60 } | |
61 wasp_impl_->setClient(client); | |
62 | |
63 testing::Mock::VerifyAndClear(mock_sink_.get()); | |
64 testing::Mock::VerifyAndClear(this); | |
65 } | |
66 | |
67 bool CompareBusses(const media::AudioBus* bus1, const media::AudioBus* bus2) { | |
68 EXPECT_EQ(bus1->channels(), bus2->channels()); | |
69 EXPECT_EQ(bus1->frames(), bus2->frames()); | |
70 for (int ch = 0; ch < bus1->channels(); ++ch) { | |
71 if (memcmp(bus1->channel(ch), bus2->channel(ch), | |
72 sizeof(*bus1->channel(ch)) * bus1->frames()) != 0) { | |
73 return false; | |
74 } | |
75 } | |
76 return true; | |
77 } | |
78 | |
79 // WebKit::WebAudioSourceProviderClient implementation. | |
80 MOCK_METHOD2(setFormat, void(size_t numberOfChannels, float sampleRate)); | |
81 | |
82 protected: | |
83 media::AudioParameters params_; | |
84 media::FakeAudioRenderCallback fake_callback_; | |
85 scoped_refptr<media::MockAudioRendererSink> mock_sink_; | |
86 scoped_refptr<WebAudioSourceProviderImpl> wasp_impl_; | |
87 | |
88 DISALLOW_COPY_AND_ASSIGN(WebAudioSourceProviderImplTest); | |
89 }; | |
90 | |
91 TEST_F(WebAudioSourceProviderImplTest, SetClientBeforeInitialize) { | |
92 // setClient() with a NULL client should do nothing if no client is set. | |
93 wasp_impl_->setClient(NULL); | |
94 | |
95 EXPECT_CALL(*mock_sink_.get(), Stop()); | |
96 wasp_impl_->setClient(this); | |
97 | |
98 // When Initialize() is called after setClient(), the params should propagate | |
99 // to the client via setFormat() during the call. | |
100 EXPECT_CALL(*this, setFormat(params_.channels(), params_.sample_rate())); | |
101 wasp_impl_->Initialize(params_, &fake_callback_); | |
102 | |
103 // setClient() with the same client should do nothing. | |
104 wasp_impl_->setClient(this); | |
105 } | |
106 | |
107 // Verify AudioRendererSink functionality w/ and w/o a client. | |
108 TEST_F(WebAudioSourceProviderImplTest, SinkMethods) { | |
109 wasp_impl_->Initialize(params_, &fake_callback_); | |
110 ASSERT_EQ(mock_sink_->callback(), &fake_callback_); | |
111 | |
112 // Without a client all WASP calls should fall through to the underlying sink. | |
113 CallAllSinkMethodsAndVerify(true); | |
114 | |
115 // With a client no calls should reach the Stop()'d sink. Also, setClient() | |
116 // should propagate the params provided during Initialize() at call time. | |
117 SetClient(this); | |
118 CallAllSinkMethodsAndVerify(false); | |
119 | |
120 // Removing the client should cause WASP to revert to the underlying sink. | |
121 EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume)); | |
122 SetClient(NULL); | |
123 CallAllSinkMethodsAndVerify(true); | |
124 } | |
125 | |
126 // Verify underlying sink state is restored after client removal. | |
127 TEST_F(WebAudioSourceProviderImplTest, SinkStateRestored) { | |
128 wasp_impl_->Initialize(params_, &fake_callback_); | |
129 | |
130 // Verify state set before the client is set propagates back afterward. | |
131 EXPECT_CALL(*mock_sink_.get(), Start()); | |
132 wasp_impl_->Start(); | |
133 SetClient(this); | |
134 | |
135 EXPECT_CALL(*mock_sink_.get(), SetVolume(1.0)); | |
136 EXPECT_CALL(*mock_sink_.get(), Start()); | |
137 SetClient(NULL); | |
138 | |
139 // Verify state set while the client was attached propagates back afterward. | |
140 SetClient(this); | |
141 wasp_impl_->Play(); | |
142 wasp_impl_->SetVolume(kTestVolume); | |
143 | |
144 EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume)); | |
145 EXPECT_CALL(*mock_sink_.get(), Start()); | |
146 EXPECT_CALL(*mock_sink_.get(), Play()); | |
147 SetClient(NULL); | |
148 } | |
149 | |
150 // Test the AudioRendererSink state machine and its effects on provideInput(). | |
151 TEST_F(WebAudioSourceProviderImplTest, ProvideInput) { | |
152 scoped_ptr<media::AudioBus> bus1 = media::AudioBus::Create(params_); | |
153 scoped_ptr<media::AudioBus> bus2 = media::AudioBus::Create(params_); | |
154 | |
155 // Point the WebVector into memory owned by |bus1|. | |
156 WebKit::WebVector<float*> audio_data(static_cast<size_t>(bus1->channels())); | |
157 for (size_t i = 0; i < audio_data.size(); ++i) | |
158 audio_data[i] = bus1->channel(i); | |
159 | |
160 // Verify provideInput() works before Initialize() and returns silence. | |
161 bus1->channel(0)[0] = 1; | |
162 bus2->Zero(); | |
163 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
164 ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get())); | |
165 | |
166 wasp_impl_->Initialize(params_, &fake_callback_); | |
167 SetClient(this); | |
168 | |
169 // Verify provideInput() is muted prior to Start() and no calls to the render | |
170 // callback have occurred. | |
171 bus1->channel(0)[0] = 1; | |
172 bus2->Zero(); | |
173 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
174 ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get())); | |
175 ASSERT_EQ(fake_callback_.last_audio_delay_milliseconds(), -1); | |
176 | |
177 wasp_impl_->Start(); | |
178 | |
179 // Ditto for Play(). | |
180 bus1->channel(0)[0] = 1; | |
181 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
182 ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get())); | |
183 ASSERT_EQ(fake_callback_.last_audio_delay_milliseconds(), -1); | |
184 | |
185 wasp_impl_->Play(); | |
186 | |
187 // Now we should get real audio data. | |
188 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
189 ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get())); | |
190 | |
191 // Ensure volume adjustment is working. | |
192 fake_callback_.reset(); | |
193 fake_callback_.Render(bus2.get(), 0); | |
194 bus2->Scale(kTestVolume); | |
195 | |
196 fake_callback_.reset(); | |
197 wasp_impl_->SetVolume(kTestVolume); | |
198 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
199 ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get())); | |
200 | |
201 // Pause should return to silence. | |
202 wasp_impl_->Pause(); | |
203 bus1->channel(0)[0] = 1; | |
204 bus2->Zero(); | |
205 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
206 ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get())); | |
207 | |
208 wasp_impl_->Play(); | |
209 | |
210 // Play should return real audio data again... | |
211 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
212 ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get())); | |
213 | |
214 // Stop() should return silence. | |
215 wasp_impl_->Stop(); | |
216 bus1->channel(0)[0] = 1; | |
217 wasp_impl_->provideInput(audio_data, params_.frames_per_buffer()); | |
218 ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get())); | |
219 } | |
220 | |
221 } // namespace webkit_media | |
OLD | NEW |